In my SQL query I am selecting data with GROUP BY and ORDER BY clauses. The table has the same numbers across multiple rows with different times in each row. So I think I want to apply a GROUP BY clause.
However in the results return the oldest time with the number, but I need the most recent time.
SELECT * FROM TABLE GROUP BY (numbers) ORDER BY time DESC
The query appears as if it should first apply GROUP BY and then ORDER BY... but the results do not appear to work this way.
Is there any way to fix this?
SELECT *
FROM table t
WHERE time = (
SELECT max(time)
FROM table
WHERE t.numbers = numbers
)
work-around is to re-write the query as:
SELECT * FROM (SELECT * FROM table ORDER BY time DESC) AS t GROUP BY numbers;
SELECT * FROM table
WHERE time IN (
SELECT MAX(time)
FROM table
GROUP BY numbers
)
According to the manual you can add desc to the group by list:
Example:
group by item1, item2 desc, item3
with or without rollup.
I've tried this and it works in Ubuntu version 5.5.58. The reference page is:
https://dev.mysql.com/doc/refman/5.7/en/group-by-modifiers.html
SELECT * FROM TABLE GROUP BY numbers DESC;
This will give you last record from group.
Thanks
Related
I am trying to run the below query but it is wrong as per MySQL syntax.
I want to select the first 100 rows then want to apply group by to it.
select customerid from customer
limit 100
group by customerid
How can I achieve it?
How about this? You need to add an aggregation column for it to work.
SELECT customerid
FROM (SELECT *
FROM customer
LIMIT 100) sub1
GROUP BY sub1.customerid;
I have two tables: ticket and ticketRules and i have a query like this:
SELECT * FROM (
SELECT * FROM ticketRules
ORDER BY
date DESC,
time DESC
) AS myTicketRules
GROUP BY ticketId
ORDER BY ticketId ASC
The first Order By (the one in the subquery) sorts data by date and time so the last ticketrule is always the first.
I group the results by ticketId so I only got the last ticketRule for each ticket.
Now I want to sort the results by ticket but if I do that the first result is also affected and tickets don't have the last ticketrule anymore but the one with the lowest id cause it's ordered by ticketId.
How can I sort only the visible records after I grouped them?
There are several issues with your query :
there should be only one ORDER BY clause (that should be placed in the outer query)
GROUP BY does not do what you think (ie it does not give access to the last ticket)
If you are trying to pull out the full latest record for each ticketId, ordered by ticketId, you can use a correlated subquery as follows :
SELECT
t.*
FROM
ticketrule t
WHERE
t.date = (
SELECT MAX(date)
FROM ticketrule
WHERE ticketId = t.ticketId
)
ORDER BY t.ticketId
you should not use a group by without aggregation function and for obtain the last value could use use an aggregation function as max( )
select ticketId, max(date)
from ticketRules
grouo by ticketId
Similar to this issue: MySQL 5.7 group by latest record
I'm not sure how to do this properly in 5.7. Also with possibility of 2nd sort column. Working query in 5.6 that I'm trying to replicate in 5.7:
SELECT id FROM test
GROUP BY category
ORDER BY sort1 DESC, sort2 DESC
id is not always the highest, so MAX(id) does not work.
Looking into the link above, the solution for single sort should be:
SELECT t1.*
FROM test t1
INNER JOIN (
SELECT category, max(sort) AS sort FROM test GROUP BY category
) t2 ON t2.category = t1.category AND t2.sort = t1.sort
But how will it work with 2 sorting?
You are using GROUP BY the wrong way.
Think of group by as a way to separate data row into different groups. Each group has multiple rows, based on the value of group by column.
Once you get those groups, selecting table columns (as in: select *) is like picking any row from that group randomly. This is not helpful nor useful.
Usually once we group records (or rows), we need to find meta information about those records. For example: get us the count of records in that group (as in: select count(*)), or the sum of values of a specific column in that group (as in: select sum(price)), or get the min, max or avg values.
So in a nutshell, when you use group by you should use on of the aggregation functions with it, otherwise it's not going to do you any good.
Why don't you have the ORDER BY at your outer query, instead?
SELECT *
FROM (
SELECT 100 AS id, 1 AS category, NULL AS sort
UNION
SELECT 200 AS id, 1 AS category, 2 AS sort
) dt
GROUP BY category
ORDER BY sort DESC;
It seems that what happened to the data when it was grouped, it took the first data while neglecting the ORDER BY DESC. On your first query, it ordered descending first then group by took the first record which is 200. And yes, this shouldn't be the way you should use GROUP BY. It is used in conjunction with aggregate functions.
when you select a column in a group by query that is not one of the columns you are grouping by, (ie, your id) you have no control over the value unless you use another aggregate function. If you want to sort, use MIN or MAX:
SELECT MAX(id), category, FROM `test2`
GROUP BY category; -- always returns 200
SELECT MIN(id), category, FROM `test2`
GROUP BY category; -- always returns 100
I've been trying to gather some data from a MySQL database for a while now.
The problem is that I want to group the data by objectid while getting only the newest data (Descending).
Everytime I try it, I either get an error, or it doesnt Descend.
My query at the moment is:
SELECT * FROM 'table' GROUP BY 'objectid' DESC
I've tried ordering by id or timestamp, but with an ascended result.
My question is similar to: http://stackoverflow.com/questions/7306082/mysql-using-group-by-and-desc
However the answers provided there didn't solve my problem.
Thanks in advance!
You also have to specify ORDER BY clause for sorting:
SELECT * FROM 'table' GROUP BY 'objectid' ORDER BY timestamp DESC
your query is wrong you should make backticks instead of single quotes
and you missed order by statment
try this
SELECT * FROM `table` GROUP BY `objectid` Order by id DESC
This will give you the most recent entry per ObjectId, ordered by descending time; it simply left joins to find all entries where there exists no newer entry for the same ObjectId.
SELECT a.*
FROM table1 a
LEFT JOIN table1 b
ON a.ObjectId=b.ObjectId
AND a.time < b.time
WHERE b.ObjectId IS NULL
ORDER BY time DESC
An SQLfiddle to test with.
Exist a better way to do what the following SQL query does? I have the feeling that table1 will be searched twice and may be that can be avoided with some trick and increase the efficient of the query, but I just can't figure out how ;( Here is the query (in MySQL):
SELECT a, SUM(count)
FROM table1
GROUP BY a
HAVING SUM(count) = (SELECT SUM(count) as total FROM table1 GROUP BY a ORDER BY total DESC LIMIT 1)
The goal is return the number(s) with the major accumulate, with its accumulate.
being table1 a two field table like:
a,count
1,10
1,30
1,0
2,1
2,100
2,4
3,10
4,50
4,55
The result with that data sample is:
2,105
4,105
Thanks in advance.
SELECT a, total FROM
(SELECT a AS a, SUM(COUNT) AS total
FROM table1
GROUP BY a) AS xyz
HAVING total = MAX(total)
Hope this will work for you
This sub-query is executed only once, and you don't have to bother with creating any pre-query as other answers may suggest (although doing so this is still correct, just not needed). Database engine will realise, that the sub-query is not using any variable dependent on the other part of the query. You can use EXPLAIN to see how the query is executed.
More on the topic in this answer:
https://stackoverflow.com/a/658954/1821029
I think you could probably do it by moving your HAVING sub-select query into its on prequery. Since it will always include a single row, you won't require any "JOIN", and it does not have to keep recomputing the COUNT(*) every time the HAVING is applied. Do it once, then the rest
SELECT
a,
SUM(count)
FROM
table1,
( SELECT SUM(count) as total
FROM table1
GROUP BY a
ORDER BY total DESC
LIMIT 1 ) PreQuery
GROUP BY
a
HAVING
SUM(count) = PreQuery.Total
This query return one row with two columns:
1- a list of comma separated values of "a" column, which have the biggest "Total"
2- and the biggest Total value
select group_concat(a), Total
from
(select a, sum(count) as Total
from table1
group by a) OnTableQuery
group by Total
order by Total desc
limit 1
Note that it queries table1 just one time. The query was already tested.