LIMIT results in MySQL? - php

ok; this has been frying my brain for hours. I think I might need a sub query, but I'm not that advanced at this kind of thing so any help or pointers in the right direction would be greatly appreciated.
Here's the Query I have....
$query = "SELECT * FROM events WHERE event_type = 'Christmas Listings' AND event_active='Yes' ORDER BY event_date ASC LIMIT 5";
$result= mysql_query($query);
OK... now for the plain english bit on what I want to achieve (to understand what I'm trying to achieve):
I want to check the event type ('event_type') is what I'm getting (ie. Christmas Listings) as there are multiple types in this column.
I want to check the event is active ('event_active') is Yes(the data in this field is Yes/No).
I want to order them by the ('event_date') ASC (the data in this field is yyyy-mm-dd) so they show the latest entry by its date from the DB.
I want to LIMIT (or in some way control the output) the results to only have 5 results displayed when running this kind of query through a WHILE statement.
OK, this all works BUT; when I get to the actual output display, i'm having a shaky output in how many results are actually display... What happens is if I have multiple events which are switched off, as in event_active is 'Off' then its almost like the argument is counting from the all the results that are (including event_active='Off') and consequently not showing how I expect them to display?
Hope this makes sense.... Any help would be gratefully received.

SELECT *
FROM events
WHERE event_type = 'Christmas Listings' AND event_active='Yes'
ORDER BY event_date
LIMIT 0, 5
so your statement is easyer to read..
You shoul use 1 / 0 instead of Yes / no
The Limit does not count all lines!
First step - doing the query including WHERE
Second step - ORDER BY
Third step - LIMIT
If you have set an index on the colum you sort. The sort will stop after 5 lines,
also means - it get faster
The ASC in the ORDER BY command is not necessary, because ASC is default

I am really not sure what you are asking, but LIMIT works as follows:
The LIMIT means that after your query is done, and ALL WHERE statements are processed, only the first 5 are returned.
ALl results where event_active is not 'Yes' will not be shown, and disregarded in everything.
This result is the same as a result where you would do the query without the limit, and just look at the first 5 lines.

That query should be fine. I'd check your data set (or even better, post it!). You might want to look into normalizing the database too. It'll help you out in the future.

The problem, I think, is with your 'event_active'.
MySQL uses 0 and 1 to indicate whether the field is true/false, yes/no, on/off. Try using 0 and 1 in your SELECT statement unless the field type on that field is VARCHAR and you actually are using those words.

Related

How can I show at least 3 record from mysql using php pdo [duplicate]

ok; this has been frying my brain for hours. I think I might need a sub query, but I'm not that advanced at this kind of thing so any help or pointers in the right direction would be greatly appreciated.
Here's the Query I have....
$query = "SELECT * FROM events WHERE event_type = 'Christmas Listings' AND event_active='Yes' ORDER BY event_date ASC LIMIT 5";
$result= mysql_query($query);
OK... now for the plain english bit on what I want to achieve (to understand what I'm trying to achieve):
I want to check the event type ('event_type') is what I'm getting (ie. Christmas Listings) as there are multiple types in this column.
I want to check the event is active ('event_active') is Yes(the data in this field is Yes/No).
I want to order them by the ('event_date') ASC (the data in this field is yyyy-mm-dd) so they show the latest entry by its date from the DB.
I want to LIMIT (or in some way control the output) the results to only have 5 results displayed when running this kind of query through a WHILE statement.
OK, this all works BUT; when I get to the actual output display, i'm having a shaky output in how many results are actually display... What happens is if I have multiple events which are switched off, as in event_active is 'Off' then its almost like the argument is counting from the all the results that are (including event_active='Off') and consequently not showing how I expect them to display?
Hope this makes sense.... Any help would be gratefully received.
SELECT *
FROM events
WHERE event_type = 'Christmas Listings' AND event_active='Yes'
ORDER BY event_date
LIMIT 0, 5
so your statement is easyer to read..
You shoul use 1 / 0 instead of Yes / no
The Limit does not count all lines!
First step - doing the query including WHERE
Second step - ORDER BY
Third step - LIMIT
If you have set an index on the colum you sort. The sort will stop after 5 lines,
also means - it get faster
The ASC in the ORDER BY command is not necessary, because ASC is default
I am really not sure what you are asking, but LIMIT works as follows:
The LIMIT means that after your query is done, and ALL WHERE statements are processed, only the first 5 are returned.
ALl results where event_active is not 'Yes' will not be shown, and disregarded in everything.
This result is the same as a result where you would do the query without the limit, and just look at the first 5 lines.
That query should be fine. I'd check your data set (or even better, post it!). You might want to look into normalizing the database too. It'll help you out in the future.
The problem, I think, is with your 'event_active'.
MySQL uses 0 and 1 to indicate whether the field is true/false, yes/no, on/off. Try using 0 and 1 in your SELECT statement unless the field type on that field is VARCHAR and you actually are using those words.

1250 - Table 'sub' from one of the SELECTs cannot be used in global ORDER clause

i'm trying to make a chat site for learning purposes, so in the course of that, I want the last 30 messages appear in ascending order w.r.t. time. Like, latest messages at the bottom, oldest one at the top. After a huge amount of googling and yet having found no solution that could help, I had to ask this.
This is the MySQL statement.
It returns the data I want but in descending order. That is, latest ones at the top. Even if I change the ASC to DESC, nothing happens.
SELECT * FROM (SELECT msg,sender FROM chatlogs WHERE user1='userone' AND user2='usertwo' ORDER BY 'timeofmsg' DESC LIMIT 30) sub ORDER BY 'sub.timeofmsg' ASC
After a lot of testing and trying solutions out, I found out by myself that when I try to sort the resultant table using PHPMyAdmin's UI, it throws the following error. Turns out it's a MySQL bug of sorts. So how to I work my way around it?
1250 - Table 'sub' from one of the SELECTs cannot be used in global ORDER clause
If you can tell me how to print the query in reverse, even that would help. But no matter how you help, please do explain how your solution would work... I'm a beginner at this.
Your first issue is that you're trying to do an "order by" on a column that is not present in the table "sub". You'll need to return it in the alias:
SELECT * FROM (SELECT msg,sender, timeofmsg FROM chatlogs WHERE user1='userone' AND user2='usertwo' ORDER BY timeofmsg DESC LIMIT 30) sub ORDER BY sub.timeofmsg ASC
Query Error, you cannot use the query as you mentioned it is not possible.

Pick random entry in MySQL database based on certain criteria

Alright, let's say my MySQL table is set up with entries similar to:
id code sold
1 JKDA983J1KZMN49 0
2 JZMA093KANZB481 1
3 KZLMMA98309Z874 0
I'd like it to pick a random ID within the ranges already in the database (or just go from 1-X) and then just assign it to a variable for my own action to be taken. So let's say we want to pick a code that isn't sold (marked as 0 and not 1), then we'd pick it.
Now, it doesn't have to be 100% random, it could check if the first one is sold, if not, keep going. But I'm not 100% sure on how to go by this. Snippets would be appreciated because I can work out things easily on my own, I just need an example to see where I am going.
How about using a WHERE and ORDER BY RAND()
SELECT id, code
FROM tablename
WHERE sold = 0
ORDER BY RAND()
LIMIT 1
If you don't need the random, then don't use it. It can affect performance very negatively. Since you mentioned in your post that it wasn't necessary, I would recomment using Ezequiel's answer above and dropping the rand. See Most Efficient Way To Retrieve MYSQL data in random order PHP for more info.
It seems that your codes are already random, so why not just take the first item; if you have many unsold records in your database, doing the typical ORDER BY RAND() will hurt the database performance.
SELECT *
FROM codes
WHERE sold = 0
LIMIT 1
FOR UPDATE;
I've also added FOR UPDATE to avoid race conditions, assuming that you're using transactions, as you update the record later (to actually sell it).
Have you tried
SELECT * FROM myTable WHERE sold = 0 ORDER BY RAND() LIMIT 1
Adding ORDER BY RAND() to the rest of your SELECT query is the most straightforward way to accomplish this.

Server-side Pagination: total row count for expensive query?

I have a simple query using server-side pagination. The issue is the WHERE Clause makes a call to an expensive function and the functions argument is the user input, eg. what the user is searching for.
SELECT
*
FROM
( SELECT /*+ FIRST_ROWS(numberOfRows) */
query.*,
ROWNUM rn FROM
(SELECT
myColumns
FROM
myTable
WHERE expensiveFunction(:userInput)=1
ORDER BY id ASC
) query
)
WHERE rn >= :startIndex
AND ROWNUM <= :numberOfRows
This works and is quick assuming numberOfRows is small. However I would also like to have the total row count of the query. Depending on the user input and database size the query can take up to minutes. My current approach is to cache this value but that still means the user needs to wait minutes to see first result.
The results should be displayed in the Jquery datatables plugin which greatly helps with things like serer-side paging. It however requires the server to return a value for the total records to correctly display paging controls.
What would be the best approach? (Note: PHP)
I thought if returning first page immediately with a fake (better would be estimated) row count. After the page is loaded do an ajax call to a method that determines total row count of the query (what happens if the user pages during that time?) and then update the faked/estimated total row count.
However I have no clue how to do an estimate. I tried count(*) * 1000 with SAMPLE (0.1) but for whatever reason that actually takes longer than the full count query. Also just returning a fake/random value seems a bit hacky too. It would need to be bigger than 1 page size so that the "Next" button is enabled.
Other ideas?
One way to do it is as I said in the comments, to use a 'countless' approach. Modify the client side script in such a way that the Next button is always enabled and fetch the rows until there are none, then disable the Next button. You can always add a notification message to say that there are no more rows so it will be more user friendly.
Considering that you are expecting a significant amount of records, I doubt that the user will paginate through all the results.
Another way is to schedule a cron job that will do the counting of the records in the background and store that result in a table called totals. The running intervals of the job should be set up based on the frequency of the inserts / deletetions.
Then in the frontend, just use the count previously stored in totals. It should make a decent aproximation of the amount.
Depends on your DB engine.
In mysql, solution looks like this :
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
Basically, you add another attribute on your select (SQL_CALC_FOUND_ROWS) which tells mysql to count the rows as if limit clause was not present, while executing the query, while FOUND_ROWS actually retrieves that number.
For oracle, see this article :
How can I perform this query in oracle
Other DBMS might have something similar, but I don't know.

Order By DESC/ASC not working within PHP Query

I have this code so far which is within 2 while loops:
mysql_query("SELECT * FROM listing WHERE
(category_id='$category' OR category_id_2='$category' OR category_id_3='$category')
AND listing_status='1' AND listing_type='1' AND listing_id='$listing_id'
ORDER BY overall DESC");
The data is showing exactly what I want, however the ORDER BY simply isn't working. I'm not too sure what it's ordering by. The overall column itself is DECIMAL(12,2).
The values are saved to only 2 decimal places. For instance, in each row it could be 2.56, 2.89. In this case I want the 2.89 to show before the 2.56. However, it's not.
Many thanks in advance.
I believe you are only selecting one element at a time in your query, something like
while(...){
$category = ...;
$listing_id = ...;
// Your query which only returns one result here
}
Then since your query only returns one result it has nothing to sort, and you see the results in the order the queries are executed.
You need to rewrite your query to select all the rows you want in one go instead of having it in a loop if you want ORDER BY to work. Using IN in your query may help you.
Have you tried casting the field as a decimal in the order by?
ORDER BY CAST(overall as DECIMAL) DESC
I have managed to solve the problem.
By implementing the 'overall' column in the first loops table, instead of the second. It orders the data first by overall, and then goes ahead and gathers the other data from the second table.
Many thanks for your help.
Try:
mysql_query("SELECT * FROM listing WHERE
(category_id='$category' OR category_id_2='$category' OR category_id_3='$category')
AND listing_status='1' AND listing_type='1' AND listing_id='$listing_id'
ORDER BY overall+0 DESC");
The query is fine. The problem is probably with how you iterate returned data. Try changing it.
If not, provide us with the whole relevant piece of your PHP code.
I don't know why, but I found out by copying and pasting from phpmyadmin that this worked to solve a similar problem. The ' is changed to ` - dunno if it's important. But definitely ASC worked with the second way.
Important - the have been stripped from the second method, put them around the table name and the column names.
instead of
$sql = "SELECT * FROM 'dczcats' ORDER BY 'first' , 'second' ASC";
I typed this
$sql = "SELECT * FROM `dczcats` ORDER BY `dczcats`.`first` , `dczcats`.`second` ASC";

Categories