Wondering how to return the 1st row in a MySQL group by vs. the last row. Returning a series of dates, but need the first one displayed.
select * from calendar where approved = 'pending' group by eventid;
Sounds like you want to use ORDER BY instead of GROUP BY:
select * from calendar where approved = 'pending' order by eventid asc limit 1;
Use the min function insead of max to return the first row in a group vs the last row.
select min(date) from calendar ...
If you want the entire row for each group, join the table with itself filtered for the min dates on each group:
select c2.* from
(select eventid, min(dt) dt from calendar
where approved = 'pending' group by eventid) c1
inner join calendar c2 on c1.eventid=c2.eventid and c1.dt=c2.dt
group by eventid;
Demo: http://www.sqlize.com/6lOr55p67c
When you use GROUP BY like that, MySQL makes no guarantees about which row in each group you get. Indeed, theoretically it could even pick some of the columns from one row and some from another. The MySQL Reference Manual says:
"MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. [...] You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate."
What you want to do instead is something like this:
SELECT
calendar.*
FROM
calendar
NATURAL JOIN (
SELECT
eventid, MIN(date) AS date
FROM
calendar
GROUP BY eventid
) AS foo
If you want to show the first AND the last element of a group-by statement, this was useful for me:
SELECT min(date) AS minn, max(date) AS maxx
FROM table_name
GROUP BY occasion
Thanks for the question
I have the solution. To select the last row in a group, use this
select * from calendar
where approved = 'pending'
group by eventid
ORDER BY max(`date`) DESC;
or this to select the first row from a group...
select * from calendar
where approved = 'pending'
group by eventid
ORDER BY min(`date`) DESC;
The DESC does not matter, it only sorts the entire filtered result by descending order, after a row from each group has been selected.
Related
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
How do I ensure, when I GROUP BY QID, that only the most recent row is returned?
ID, QID, VALUE, TIMESTAMP
45,1,Male,1362044759
58,1,Female,1362045122
59,1,Male,1362045149
60,1,Female,1362045153
82,1,Female,1362045863
83,1,Female,1362045887
92,1,Male,1362046012
101,1,Female, 1362046401
SELECT ID, QID, VALUE, TIMESTAMP FROM table GROUP BY ID
...returns the first row. I can't simply do a LIMIT 1, as this is just an example, there are lots of QIDs in the table, which are all grouped.
Thanks.
I'm assuming here you want the "latest" row for each QID. You would normally use a derived-table subquery to get each QID's latest TIMESTAMP value and then join on that:
SELECT ...
FROM myTable AS t
INNER JOIN (SELECT QID, MAX(`TIMESTAMP`) AS MaxT FROM myTable GROUP BY QID) l
ON t.QID = l.QID AND l.maxT = t.`TIMESTAMP`
This is also assuming your TIMESTAMP column increases as time goes on.
If you want the most recent record returned:
SELECT *
FROM TBL
ORDER BY `TIMESTAMP` DESC
LIMIT 1;
Otherwise, if you want to get the most recent record for each group of QID check this Stack Overflow Post that treat your same problem with optimal solutions.
You could use 'GROUP_CONCAT' in order to extract grouped data.
SELECT GROUP_CONCAT(ID ORDER BY TIMESTAMP DESC) AS latest_id
Sometimes I want to get just one row of each similar value, I ussually do somethingl ike this:
SELECT * GROUP BY Text ORDER BY Date DESC
My problem using GROUP to select similar rows is that I don't get the values from the latest rows in the row (I'm not quite sure what's the criteria to choosing the row that stays). I want to retain only the newest row in the group.
I know how to do it with a self join but when statements are already very long it seems a bit complicated. Is there any shorter method? Maybe using DISTINCT instead of GROUP BY?
Assuming you have a table that has multiple columns and two of which are GroupID and DATE. If you want to select the latest record for each GroupID, you need to have a subquery which gets the latest Date for each GroupID, example
SELECT a.* -- this just selects all records from original table
FROM tableName a
INNER JOIN
(
-- this subquery gets the latest DATE entry for each GROUPID
SELECT GroupID, MAX(DATE) maxDate
FROM tableName
GROUP BY GroupID
) b ON a.GroupID = b.GroupID AND
a.Date = b.maxDate
if this answer is not clear, please do ask :D
Did you try to use the max function:
SELECT A,B,max(Date) GROUP BY Text
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