This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Closed 2 months ago.
I have a table named Work_Items like this:
Assume there are lots of Names (i.e., E,F,G,H,I etc.,) and their respective Date and Produced Items in this table. It's a massive table, so I'd want to write an optimised query.
In this, I want to query the latest A,B,C,D records.
I was using the following query:
SELECT * FROM Work_Items WHERE Name IN ('A','B','C','D') ORDER BY Date DESC OFFSET 0 LIMIT 4
But the problem with this query is, since I'm ordering by Date, the latest 4 records I'm getting are:
I want to get this result:
Please help me in modifying the query. Thanks.
On MySQL 8+, we can use ROW_NUMBER:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Date DESC) rn
FROM Work_Items
WHERE Name IN ('A', 'B', 'C', 'D')
)
SELECT Name, Date, ProducedItems
FROM cte
WHERE rn = 1
ORDER BY Name;
You can use inner join as follows, its working on any mysql version:
select w.name, w.`date`, w.ProducedItems
from _Work_Items w
inner join (
select name, max(date) as `date`
from _Work_Items
group by name
) as s on s.name = w.name and s.`date` = w.`date` ;
This question already has answers here:
How to find the maximum count using mysql?
(9 answers)
Closed 1 year ago.
I've been trying to get the maximum number from a set of different values.
suppose,
i have table with values,
id val
A 1
A 2
A 3
B 4
B 5
C 6
so i want to get the maximum number of id and first i did get the count and tried to get maximum
my sql query is,
SELECT MAX (ID_COUNT) id_count
FROM (SELECT id,COUNT(id) ID_COUNT
FROM tab1
GROUP BY id)
I want an ouput 3 since A is repeated 3 times and is the maximum.
it was supposed to work. but now im getting an error saying derived table value should have an alias. but i did give an alias.
what should i do?
thanks in advance...
You need to specify an alias for the sub select
SELECT MAX (ID_COUNT) id_count
FROM (SELECT id,COUNT(id) ID_COUNT
FROM tab1
GROUP BY id) tab2
You can try the below -
SELECT id,COUNT(id) ID_COUNT
FROM tab1
GROUP BY id
order by ID_COUNT desc
limit 1
This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
How can I SELECT rows with MAX(Column value), PARTITION by another column in MYSQL?
(22 answers)
MySQL - How to select rows with max value of a field
(3 answers)
Closed 1 year ago.
I'm looking for a way to display a column in my table without aggregating it (column store)
SELECT id, name, max(cost), store
FROM test
group by 1,2,4
But in the table im using there are some row that shares the same id,name,license with different machine, and Ideally I'd like to get in return only a single row, with max(cost), if they share the same first 2 columns and only display the last column - without using it to group by.
actual outcome:
id
name
max(cost)
store
1
Joe
30
store1
1
Joe
50
store2
but my desired result will be:
id
name
max(cost)
store
1
Joe
50
store2
Can it even be done?
You seem to want the row with the maximum cost. A typical method uses row_number();
select t.*
from (select t.*,
row_number() over (partition by id, name order by cost desc) as seqnum
from test t
) t
where seqnum = 1;
No aggregation is needed.
You can also use a correlated subquery:
select t.*
from test t
where t.cost = (select max(t2.cost)
from test t2
where t2.id = t.id
);
This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Closed 2 years ago.
I have the following query.
SELECT MAX(activity_id), group_id, parent_group_id FROM dashboard_activity_detail WHERE account_id = 8997 AND parent_group_id IN (5118,5026,4522,3983,3586,3278,3227) AND activity_type_id = 18 GROUP BY parent_group_id;
My expectation is that the group_id will be returned associated with the largest activity_id. There are multiple rows with the same parent_group_id in the table. What I get back is a value from a different row. The activity_id is correct and the parent_group_id is correct but I get a value from a different row for the group_id.
What am I missing? I've tried order by and various other methods with the same result.
You expectation is wrong. You query is malformed because the SELECT columns are inconsistent with the GROUP BY columns.
Use window functions (available in MySQL 8+):
SELECT da.*
FROM (SELECT da.*,
ROW_NUMBER() OVER (PARTITION BY parent_group_id ORDER BY activity_id DESC) as seqnum
FROM dashboard_activity_detail da
WHERE account_id = 8997 AND
parent_group_id IN (5118,5026,4522,3983,3586,3278,3227) AND
activity_type_id = 18
) da
WHERE seqnum = 1;
This question already has answers here:
What is the simplest SQL Query to find the second largest value?
(46 answers)
Closed 2 years ago.
Let's say I have a table similar to the following:
Item Description Time
----- ----------- -----
ItemA1 descript 08-16-2013 00:00:00
ItemA2 descript 08-16-2013 00:00:00
ItemA3 descript 08-16-2013 00:00:00
.
.
ItemAN descript 08-16-2013 00:00:00
ItemB1 descript 08-13-2013 00:00:00
ItemB2 descript 08-13-2013 00:00:00
ItemB3 descript 08-13-2013 00:00:00
.
.
ItemBN descript 08-13-2013 00:00:00
.
.
.
ItemX1 descript 01-13-2012 00:00:00
ItemX2 descript 01-13-2012 00:00:00
ItemX3 descript 01-13-2012 00:00:00
.
.
ItemXN descript 01-13-2012 00:00:00
Groups of items are added periodically. When a group of items is added they are all added with the same "Time" field. "Time" essentially serves as a unique index for that item group.
I want to SELECT the group of items that have the second highest time. In this example my query should pull the "B" items. I know I can do max(time) to SELECT the "A" items, but I don't know how I would do second last.
My "Time" columns are stored as TIMESTAMP if that means anything.
You can try something like:
SELECT MAX(Time)
FROM yourTable
WHERE Time < (SELECT MAX(Time) FROM yourTable)
SQLFiddle Demo
One approach:
SELECT t.*
FROM mytable t
JOIN ( SELECT l.time
FROM mytable l
GROUP BY l.time
ORDER BY l.time DESC
LIMIT 1,1
) m
ON m.time = t.time
This uses an inline view (assigned an alias of m) to return the second "greatest" time value. The GROUP BY gets us a distinct list, the ORDER BY DESC puts the latest first, and the "trick" is the LIMIT, which returns the second row. LIMIT(m,n) = (skip first m rows, return next n rows)
With that time value, we can join back to the original table, to get all rows that have a matching time value.
Performance will be enhanced with an index with leading column of time. (I think MySQL should be able to avoid a "Using filesort" operation, and get the result from the inline view query fairly quickly.)
But, including a predicate in the inline view query, if you "know" that the second latest time will never be more than a certain number of days old, won't hurt performance:
WHERE l.time > NOW() + INTERVAL -30 DAYS
But with that added, then the query won't return the "second latest" group if it's time is more than 30 days ago.
The SELECT MAX(time) WHERE time < ( SELECT MAX(time) approach to get the second latest (the approach given in other answers) might be faster, especially if there is no index with leading column of time, but performance would best be gauged by actual testing. The index with leading column of time will speed up the MAX() approach as well.)
The query I provided can be easily extended to get the 4th latest, 42nd latest, etc, by changing the LIMIT clause... LIMIT(3,1), LIMIT(41,1), etc.
This should give you second biggest time:
SELECT time FROM table GROUP BY time ORDER BY time DESC LIMIT 1,1
SELECT T1.ITEM
FROM YOURTABLE T1
WHERE T1.TIME = ( SELECT MAX(T2.TIME)
FROM YOURTABLE T2
WHERE T2.TIME < ( SELECT MAX(T3.TIME)
FROM YOURTABLE T3
)
)
Get second, third, fourth......Nth highest value using following query:
SELECT MIN(value) from yourTable WHERE value IN( SELECT TOP N value FROM yourTable ORDER BY value DESC)
Replace N by you number i.e. N=2 for second highest value, N=3 for third highest value and so on. So for second highest value use:
SELECT MIN(value) from yourTable WHERE value IN( SELECT TOP 2 value FROM yourTable ORDER BY value DESC)
Something really straightforward like this should work
select * from my-table where time =
(Select top 1 time
from (select top 2 time from my-table order by time desc)
order by time asc)
Here is another solution which I think should work for your problem:
CREATE TEMPORARY TABLE xHighest AS (SELECT DISTINCT Time FROM `my-table` ORDER BY Time DESC LIMIT 1,1);
SELECT * FROM `my-table` JOIN xHighest ON (my-table.Time = xHighest.Time);
You can choose if second, third, ... highest value should be used by changing the first parameter of LIMIT.
MYSQL: limit base solution
Example: records 1, 2, 3, 4, 5.
LIMIT 2,1 means it will return 3rd highest number, as LIMIT 1,1 return 2nd highest number and so on
SELECT rc.rc_officer_id FROM recovery_complain_officer rc ORDER BY rc.rc_officer_id DESC LIMIT 2,1
Leftfield-ish answer, but this allows you to select n-1 ordered values from a single table as you want (credit to the https://stackoverflow.com/a/35234692/618320 answer by #Uueerdo), with nearly no extra cost.
You can use GROUP_CONCAT(DISTINCT...), followed by some SUBSTRING(...),
SELECT
SUBSTRING_INDEX(groupTime, ',', 1) AS time1,
SUBSTRING_INDEX(SUBSTRING_INDEX(groupTime, ',', 2), ',', -1) AS time2,
SUBSTRING_INDEX(SUBSTRING_INDEX(groupTime, ',', 3), ',', -1) AS time3
FROM (
SELECT GROUP_CONCAT(DISTINCT Time ORDER BY Time DESC) groupTime FROM mytable) t
The inner query would give you a single-row result back like "08-16-2013 00:00:00,08-13-2013 00:00:00,01-13-2012 00:00:00", and splitting that string up the way we are doing, gives you a table result like,
time1 time2 time3
--------- ------------ ------------
08-16-2013 00:00:00 08-13-2013 00:00:00 01-13-2012 00:00:00
Maybe TOP and START AT can help here.
I have used this in Sybase SQL.
SELECT TOP 1 START AT 2 * FROM Table_Name ORDER BY CREATEDDATETIME DESC;