I want to get the most recent 100 events that happened. The events are scattered across multiple tables. Here is an example:
SELECT * FROM log_items_purchased ORDER BY timestamp DESC LIMIT 100
UNION
SELECT * FROM log_items_fulfilled ORDER BY timestamp DESC LIMIT 100
UNION
SELECT * FROM log_items_shipped ORDER BY timestamp DESC LIMIT 100
This will return up to 300 records. I would then take the result set, order by timestamp, and take the first 100 records. How can I perform this in a single SQL query, where SQL will only return 100 records in the result set.
I realize that it would be possible to do this by removing the LIMIT 100 from each query, and then make an outer query that adds LIMIT 100, but these tables are really big, and that's really inefficient.
Put it in a subquery, then use LIMIT 100 in the main query.
SELECT *
FROM (
SELECT * FROM log_items_purchased ORDER BY timestamp DESC LIMIT 100
UNION
SELECT * FROM log_items_fulfilled ORDER BY timestamp DESC LIMIT 100
UNION
SELECT * FROM log_items_shipped ORDER BY timestamp DESC LIMIT 100
) AS x
ORDER BY timestamp DESC
LIMIT 100
If you want to do this in SQL, use a subquery:
SELECT e.*
FROM ((SELECT * FROM log_items_purchased ORDER BY timestamp DESC LIMIT 100
) UNION ALL
(SELECT * FROM log_items_fulfilled ORDER BY timestamp DESC LIMIT 100
) UNION ALL
(SELECT * FROM log_items_shipped ORDER BY timestamp DESC LIMIT 100
)
) e
ORDER BY timestamp DESC
LIMIT 100;
Note: Do not use UNION. It incurs overhead to remove duplicates.
I think this will work
(SELECT * FROM log_items_purchased ORDER BY timestamp DESC LIMIT 100)
UNION
(SELECT * FROM log_items_fulfilled ORDER BY timestamp DESC LIMIT 100)
UNION
(SELECT * FROM log_items_shipped ORDER BY timestamp DESC LIMIT 100)
ORDER BY timestamp DESC LIMIT 100
Related
I have table with dates and int value (viewCount), I need to get last 20 rows by date and than sort these rows by viewCount value.
I ended with this but its not ordering by viewCount.
SELECT *
FROM `videos`
ORDER BY `videos`.`date` DESC, `videos`.`viewCount` DESC
limit 20
Thanks with help!
You can use a subquery:
SELECT v.*
FROM (SELECT v.*
FROM videos v
ORDER BY v.date DESC
LIMIT 20
) v
ORDER BY v.viewCount DESC ;
here's the problem
I need to fetch rows from my table where date created is less than 24 hours ago and ORDER them by likes and then UNION them with the rest of rows in the same table but I want the remaining rows to be ORDERED by date created.
in other words I need separate ORDER BY clause for each SELECT.
to be more clear, it's something like this:
SELECT *
FROM (SELECT *
FROM 'table'
WHERE 'date_created' > timestampadd(hour, -24, now())
ORDER BY 'likes' DESC
UNION
SELECT *
FROM 'table'
WHERE
ORDER BY date_created DESC ) AS Results
LIMIT 10 OFFSET 0
thanks for this awesome community :)
Try this:
SELECT *, (date_created > timestampadd(hour, -24, now()) AS recent
FROM table
ORDER BY recent DESC, IF(recent, likes, 0) DESC, IF(!recent, date_created, 0) DESC
LIMIT 10 OFFSET 0
I need to select 40 rows with date from today and 10 records with older date, ordered by date.
If MySQL supported negative offset, it would look like this:
SELECT * FROM `mytable` WHERE `date` >= '2013-10-29' ORDER BY date LIMIT -10, 40;
Negative offset is not supported. How can I solve the problem? Thanks!!!
Use UNION to combine two queries:
(
SELECT *
FROM mytable
WHERE date < '2013-10-29'
ORDER BY date DESC
LIMIT 10
) UNION ALL (
SELECT *
FROM mytable
WHERE date >= '2013-10-29'
ORDER BY date
LIMIT 40
)
ORDER BY date -- if results need to be sorted
I'm trying to select 10 rows from today's date in either direction (forward and backwards in time) and in date order. The best I've got so far is:
SELECT * FROM (
SELECT * FROM foo WHERE dt >= now() ORDER BY dt ASC LIMIT 10
UNION
SELECT * FROM foo WHERE dt < now() ORDER BY dt DESC LIMIT 10
) ORDER BY dt ASC;
Is there a nicer/more efficient way to do this?
Thanks.
Your idea is sound, but this is the correct query for it.
SELECT * FROM (
SELECT * FROM (SELECT * FROM foo WHERE dt >= now() ORDER BY dt ASC LIMIT 10) A
UNION ALL
SELECT * FROM (SELECT * FROM foo WHERE dt < now() ORDER BY dt DESC LIMIT 10) B
) C
ORDER BY dt ASC;
Only one ORDER BY clause is permitted per level of query, so you actually need to further subquery the A and B parts shown. Also, UNION ALL avoids a sort operation, since you know the two sets are distinct.
An index on foo.dt will ensure that this query is as fast as can be.
Instead of you can use simple query
(SELECT * FROM one WHERE dt >= now() ORDER BY dt ASC LIMIT 10)
UNION ALL
(SELECT * FROM one WHERE dt < now() ORDER BY dt DESC LIMIT 10)
I want to show the last 10 lines of a table ordered by date added ascending.
I know I can select count(*) as total from tableName and $offset = 10 - total then select * from tableName order by dateadded asc limit 10 offset $offset
NOTE: I need the results to be displayed in reverse, oldest at the top, newest at the bottom therefore simply ordering by desc does not produce what i need
Can this be done in one query?
Just order DESC...
SELECT *
FROM tableName
order by dateadded DESC
Limit 10
To swap the order of the results
SELECT *
FROM (
SELECT *
FROM tableName
order by dateadded DESC
Limit 10
) r
ORDER BY dateadded