display most recent query result - php

i have a query that i use to count the number of rows as a result, but i would also like to print out the most recent row of that query, in a view, but only that recent query instead of the whole array
basically i use this query, then run a count to display the amount of rows which is a count i display, but i also want to display the latest date, location, and code, it can only get it to display all

2 options...
Select * from table order by primary_key desc;
count the results and print the first (most recent) row
or run two separate queries...
select count(primary_key) as num_rows from table;
select * from table order by primary_key desc limit 1;

Related

Return random rows only once in mysql

I am trying to retrieve random rows from mysql using RAND() function. But in result rows are repeating more than once. Is there any way to return random rows in such a way that a row is returned only once?
My query is: SELECT h.recid recid, h.name name, h.subtitle subtitle, h.pricingfrom pricingfrom FROM holydays h ORDER BY RAND()
I found this solution but I didnt understand how it works as I don't have any limits...
Any answer will be appreciated.!
The ORDER BY clause of a query has nothing to with the result set, except maybe if LIMIT is being used, which it is not here. It sounds to me like your table has some duplicate records. If you want a random ordering with no duplicates, then select with DISTINCT:
SELECT DISTINCT
recid,
name,
subtitle,
pricingfrom
FROM holydays
ORDER BY RAND();
it's work by order by taking random columns
ex, there is id, name, emai then some time it order id,name,email or some time name,id,emai etc. etc. and it some time order in asc and some time in desc. That's logic.

MYSQL count rows instead of showing results

So I have the following query, which I use it to get some analytics stats.
SELECT count(*) as total,CONCAT(YEAR(created),'-',MONTH(created),'-',DAY(created))
as date_only FROM logs where action = 'banner view'
and created BETWEEN '2015-07-03 21:03'
AND '2017-08-02 21:03' group by date_only order by created asc
This works, and it gives me this:
So what I actually need is, the total count of the rows in this case is 20, this is a dummy example, but I need to use this count to check before showing the stats if the data is too big to be displayed on a graphic.
Can this be achieved?
//LE
So the process will be like this:
1. Get a count of the total rows, if the count of rows is smaller than X(number will be in config and it will be a basic if statement), then go ahread and run the above query.
More info:
I actually use this query to display the stats, I just need to adapt it in order to show the total count rows
So the result of thquery should be
total | 20 in this case
I think you would want to use a derived table. Just wrap your original query in parenthesis after the FROM and then give the derived table an alias (in this case tmp). Like so:
SELECT count(*) FROM (
SELECT count(*) as total,CONCAT(YEAR(created),'-',MONTH(created),'-',DAY(created))
as date_only FROM logs where action = 'banner view'
and created BETWEEN '2015-07-03 21:03'
AND '2017-08-02 21:03' group by date_only order by created asc
) as tmp;
If I understand what you want to do correctly, this should work. It should return the actual number of results from your original query.
What's happening is that the results of the parenthesized query are getting used as a sort of virtual table to query against. The parenthesized query returns 20 rows, so the "virtual" table has 20 rows. The outer count(*) just counts how many rows there are in that virtual table.
Based on the PHP tag, I assume you are using PHP to send the queries to MySQL. If so, you can use mysqli_num_rows to get the answer.
If your query result is in $result then:
$total = mysqli_num_rows($result);
Slightly different syntax for Object Oriented style instead of procedural style.
The best part is you don't need an extra query. You perform the original query and get mysqli_num_rows as an extra without running another query. So you can figure out pagination or font size or whatever and then display without doing the query again.
This is an small query but works fine, and give me the total number of rows, you just need add your conditions.
SELECT COUNT(*) FROM table WHERE field LIKE '%condition%'
The group by I think you need to eliminated, becouse, this instead of count the records, divide in all your group by, example: records = 4, with group by you have
1
1
1
1
I hope this help you
You can try this way .
SELECT COUNT(*) FROM ( SELECT count(*) as total,CONCAT(YEAR(created),'-',MONTH(created),'-',DAY(created))
as date_only FROM logs where action = 'banner view'
and created BETWEEN '2015-07-03 21:03'
AND '2017-08-02 21:03' group by date_only HAVING total >=20 ) temp

Counting all rows with a limit

I need to filter (using where clauses) the rows in my table, count the total number of rows from this filter and then limit number of rows for pagination.
What is quickest/more efficient?
Count the rows with sql query. Select the rows with a limit with sql query.
Select all rows with sql query. Count the array with PHP. Split the array with PHP.
Or is there another way to count all rows and get a limited set of the results out?
You should use SQL_CALC_FOUND_ROWS and the FOUND_ROWS() function to return the total number of rows even when a LIMIT is applied to the returned results. After you run your query the results will be returned, and then you can run SELECT FOUND_ROWS() to return the total number of rows without having to run the query again.
SELECT SQL_CALC_FOUND_ROWS * FROM my_table WHERE column = 'something' LIMIT 10;
SELECT FOUND_ROWS() AS total_results;
Use two queries, one to retrieve total number of rows, another to get the rows. The first argument in LIMIT clause specifies the offset of the first row ( current_page * post_per_page ), and the second specifies the maximum number of rows to return ( post_per_page ).
SELECT COUNT(*) AS num_rows FROM table;
SELECT * FROM table LIMIT start, length;
The MySQL LIMIT should do the trick for you. This is a more efficient approach, as it helps in fetching only the relevant records to be displayed and nothing else.
Note that the startingIndex, numberOfRecordsPerPage variables should be set before executing the query.
SELECT * FROM MY_TABLE where
(...) //ALL CONDITIONS go here
LIMIT startingIndex, numberOfRecordsPerPage;
From the MySQL Reference
With two arguments, the first argument specifies the offset of the
first row to return, and the second specifies the maximum number of
rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
In order to identify whether or not to expect any records in return, one must first run the query (with COUNT and without any LIMIT condition):
`SELECT COUNT(*) FROM MY_TABLE where (...) //ALL CONDITIONS go here`
and store it separately. This shall be the total records applicable to the WHERE clauses given.
If the sum startingIndex+numberOfRecordsPerPage is >= TOTAL_COUNT then that paginated set shall be the last of the whole list and the user should not be allowed to click the NEXT button.
PS: Also, as pointed out in the comments, you might want to look at a framework alternative, like Criteria API for Java, to the heavy weightlifting, particularly if your WHERE conditions are also generated dynamically.

Join SQL query that has single id/row in 1 table, but links to multiple rows(same id) in another table?

First sorry for the long question title.
My question/situation is as such.
1.) I have 2 tables in mysql
2.) In first table, each listing has a unique id(each listing is in 1 row)
3.) In the second table it has the name/tags for images linked to the listing id,from the first table
4.) Each listing can have multiple images(multiple row in the second table).
What i am trying to do is to pull all the listings from table 1 and then use the listing.id from table one to pull all the rows of images from table 2 that are linked to the listing.id.
I am confused at the moment because there are multiple rows that has the same listing.id from table 2. ANd i tried query to display* but it only echo the last image(row) from table 2.
It doesnt seem to work when i join the 2 tables. And i am not sure if i query it twice then push array together.
Thanks for your time
$result=mysqli_query($con,"SELECT * FROM Listing JOIN listingpic ON
(Listing.id = listingpic.listingid)
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+300 DAY GROUP BY Listing.id ORDER BY Listing.id DESC") or die( mysqli_error($con));
while ($row = mysqli_fetch_assoc($result))
{
$output[] = $row;
}
if (!empty($output)){
echo json_encode( $output );}
else{
echo json_encode( [] );
}
You only get one result per id, because you used GROUP BY Listing.id. If you do not group them, you get one result row for each table 2 row, including the Listing id each time.
If you wish to retrieve the data in one query in the form "one id: multiple data", you can use GROUP_CONCAT for example and then explode() the retrieved string result.
Otherwise get all ids from table 1 and then iterate over them in PHP and do one additional query per ID
Pro tip: Don't use the viciously confusing MySQL extension to GROUP BY. Read this: http://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html
Pro tip: Don't use SELECT *, especially when you're joining tables. Instead, enumerate the columns you want in your result set.
Inherent to SQL is the idea that resultsets, like tables, are rectangular. They have rows and columns. Each row usually represents some real world item -- an "entity" -- and each column represents some attribute of that entity.
The result set you describe will, inherently, repeat information from your first table so it can show the info from the second table row by row.
What you want for a query is this, I think.
SELECT Listing.id, listing.date,
listingpic.id, listingpic.url, listingpic.caption
FROM Listing
JOIN listingpic ON Listing.id = listingpic.listingid
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+300 DAY
ORDER BY Listing.id DESC, listingpic.id
This will give you one row per image.
If you're running out of memory it's because your result set is massive. You may want to limit it somehow, either using a first and last publication date:
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+300 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate())+293 DAY
or with a LIMIT clause.
ORDER BY Listing.id DESC, listingpic.id
LIMIT 100

Counting all results of MySQL query for paging

I am building a search page, each page featuring 10 results. For that purpose, I would like to display pages numbers at the bottom (like in Google for example) so a user can jump to a specific page result. In order to do that I need to know the overall count of the query (e.g., if I show 10 results per page and the specific query returns 73 rows in my Table, i would need to display links to 8 pages).
The only way I can think of is using the following (obviously inefficient) query:
// Query for the current page
$res = mysql_query("select * from TABLE WHERE COL='Sample' LIMIT $offset,10");
// Geeting the total count do I can build links to other pages
$res2 = mysql_query("select COUNT(*) fromTABLE WHERE COL='Sample'");
Is that the only way to do it?
Thanks,
Danny
you can use
SQL_CALC_FOUND_ROWS
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
SQL_CALC_FOUND_ROWS tells MySQL to
calculate how many rows there would be
in the result set, disregarding any
LIMIT clause. The number of rows can
then be retrieved with SELECT
FOUND_ROWS()

Categories