Select first row for each different column value [duplicate] - mysql

This question already has answers here:
Get records with max value for each group of grouped SQL results
(19 answers)
Closed 5 years ago.
Having a table T like this:
ID DateTime asha
AF35 15-01-17 af
AF35 14-01-17 la
AF35 13-01-17 fi
DF57 15-01-17 sk
DF57 14-01-17 sj
DG36 15-01-17 be
DG36 14-01-17 dh
What is the simplest mysql query to have only first row for each unique ID returned, being ordered by the most recent DateTime?
I the expected result would be something like this:
ID DateTime asha
AF35 15-01-17 af
DF57 15-01-17 sk
DG36 15-01-17 be
I tried SELECT * FROM T GROUP BY ID ORDER BY DateTime, however, mysql returns an error for not adding the other columns to the clause. And if I add them, I still get duplicated results for the ID.

My favorite method to write this query is with a not exists clause:
select *
from T as t1
where not exists (
select 1
from T as t2
where t2.ID = t1.ID
and t2.DateTime > t1.DateTime
)

SELECT Distinct(ID),DateTime,asha FROM T GROUP BY ID ORDER BY DateTime desc
use above query to unique Id records.

Related

Get Top 5 latest records for different IDs in SQL [duplicate]

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` ;

Query is returns the wrong value for row [duplicate]

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;

is it possible to do it in one query with dynamic table name without prepare statement? [duplicate]

This question already has answers here:
MySQL SELECT only not null values
(11 answers)
Closed 6 years ago.
I have a survey record table which I want to count the latest survey recoders with field 'complete' is''Y', while the latest survay name is in another table with the createdate, that's mean, the table name is dynamic,
select 'complete' count(*)
from(
select 'survey_name'
from survey
Where active=''Y''
order by cratedate desc
limit 1
)
but it cant work
record table: (name is dynamic)
id | complete | submitdate
survey table:
survay_name | active | cratedate
I knew it should be done by prepare statement, but my system (joomla + plotalot) only accept one query.
You need to add 'id' column in your Survey table
Of Course, the ID must link between SURVEY and RECORD table
then,, you can use below query
SELECT COUNT(r.complete) as complete, s.survay_name, s.createDate
FROM survey s
LEFT JOIN record r ON s.id = r.id
WHERE s.active = 'Y' AND r.complete = 'Y'

Limit SQL Results to one result per pkey searched using "in" [duplicate]

This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Closed 8 years ago.
I have a history table which I would like to use to find the latest user in which updated specific items. Here is the query I have so far:
SELECT *
FROM `history`
WHERE `pKey`
IN ( 13309, 13311, 13951, 14244, 1500, 15558, 15691, 15938, 9769 )
ORDER BY `history`.`time` DESC
LIMIT 0 , 30
This returns multiple history results for each pkey. Is there a way to limit the results to only the latest (based on time) entry from the specific pkey?
So for example:
Right now pkey 13309 has multiple results returned. The query should only return the latest result for it. Same goes for 13311... etc.
This should do:
SELECT h.*
FROM `history` as h
INNER JOIN (SELECT `pkey`, MAX(`time`) as MaxTime
FROM `history`
WHERE `pkey` IN (13309, 13311, 13951, 14244, 1500,
15558, 15691, 15938, 9769)
GROUP BY `pkey`) as t
ON h.`pkey` = t.`pkey`
AND h.`time` = t.`MaxTime`
this should work. Just grouping all the rows that have the same pkey. I think this will work. Comment with a feedback.
Select * from (
SELECT *
FROM `history`
WHERE `pKey`
IN ( 13309, 13311, 13951, 14244, 1500, 15558, 15691, 15938, 9769 )
ORDER BY `history`.`time` DESC) as t1 group by pKey

GROUP BY return the first record [duplicate]

This question already has answers here:
How to optimize MySQL query (group and order)
(4 answers)
Closed 1 year ago.
As far as I know mysql GROUP BY groups to the last record found.
Is there any solution to GROUP BY the first record?
I have setup the ORDER in SQL command and I need GROUP BY return the first record and not the last.
EDIT
Here is the Query
SELECT
DISTINCT(master.masterID),
langData.*,
master.*
FROM master_table as master
INNER JOIN lang_table as langData ON
langData.masterID=master.masterID
GROUP BY master.masterID
ORDER BY
CASE
WHEN langData.lang='currentLang' THEN 1 ELSE 999 END ,
master.name desc LIMIT 0,10
The query above select the masterID for multi language table and suppose to return FIRST the records in currentLang and order them by name AND THEN all other languages.
Don't ask me why I don't set the language in JOIN. This is the way to be done.
So everything works fine so far expect the scenario that I have a record with languages en and fr. If currentLang is en then based on
langData.lang='currentLang' THEN 1 ELSE 999 END
the en order is 1 and fr order is 999 and instead of getting the value of en I get the value of fr.
That's why I want to group to the first row.
I assume you are talking of something like
SELECT *
FROM mytable
GROUP BY
column
You shouldn't use unaggregated expressions in GROUP BY unless they are all same within the group.
If you want to return the record holding the least value of an expression within a group, use this:
SELECT mo.*
FROM (
SELECT DISTINCT column
FROM mytable
) md
JOIN mytable mo
ON mo.id =
(
SELECT id
FROM mytable mi
WHERE mi.column = md.column
ORDER BY
mi.column, mi.someorder
LIMIT 1
)
Add LIMIT 1 to your query.