aggregate function, newest date - sql

I have a table
date name
2014-01-01 AAA
2014-01-01 BBB
2014-01-01 CCC
2014-01-01 DDD
2015-05-05 AAA
2016-09-09 AAA
2016-09-09 BBB
and I want to have only the newest information about every person:
date name
2016-09-09 AAA
2016-09-09 BBB
2014-01-01 CCC
2014-01-01 DDD
I can simply write
SELECT MAX(date), name
FROM table1
GROUP BY name;
but if I want to add another column, it doesn't work
SELECT MAX(date), name, address
FROM table1
GROUP BY name;
(doesn't work)
SELECT MAX(date), name, address
FROM table1
GROUP BY name, address;
(it works, but I want to have only one record for one person)
How can I do it?

Assuming your dates for each name are unique, it's quite simple to solve using a derived table and join, like this:
SELECT maxdate, t.name, t.address
from table1 t
inner join
(
SELECT MAX(date) as maxdate, name
FROM table1
GROUP BY name
) d on(t.date = d.maxdate and t.name = d.name)

In SQL-Server you can use ROW_NUMBER() in following:
SELECT [date], name, address
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY name, address ORDER BY [date] DESC) rn
FROM Table1
)x
WHERE rn = 1

Try this
SELECT * FROM `table1` group by name order by name, date

Try using DISTINCT
SELECT MAX(date), distinct name
FROM table1
GROUP BY name;
may be this will work .

Related

Select the duplicate rows with specific values

How can I only get the data with the same ID, but not the same Name?
The following is the example to explain my thought. Thanks.
ID Name Date
123 Amy 08/03/2022
123 Amy 12/03/2022
456 Billy 08/03/2022
456 Cat 09/03/2022
789 Peter 10/03/2022
Expected Output:
ID Name Date
456 Billy 08/03/2022
456 Cat 09/03/2022
How I have done.
select ID, Name, count(*)
from table
groupby ID, Name
having count(*) > 1
But the result included the following parts that I do not want it.
ID Name Date
123 Amy 08/03/2022
123 Amy 12/03/2022
One approach would be to use a subquery to identify IDs that have multiple names.
SELECT *
FROM YourTable
WHERE ID IN (SELECT ID FROM YourTable GROUP BY ID HAVING COUNT(DISTINCT Name) > 1)
I'd join the table to its self like this:
SELECT DISTINCT
a.Id as ID_A,
b.Id as ID_B,
a.[Name] as Name_A
FROM
Test as a
INNER JOIN Test as b
ON A.Id = B.Id
WHERE
A.[Name] <> B.[Name]
Do you want
SELECT * FROM table_name
WHERE ID = 456;
or
SELECT * FROM table_name
WHERE ID IN
(SELECT
ID
FROM table_name
GROUP BY ID
HAVING COUNT(DISTINCT name) > 1
);
?
Window functions are likely to be the most efficient here. They do not require self-joining of the source table.
Unfortunately, SQL Server does not support COUNT(DISTINCT as a window function. But we can simulate it by using DENSE_RANK and MAX
WITH DistinctRanks AS (
SELECT *,
rnk = DENSE_RANK(*) OVER (PARTITION BY ID ORDER BY Name)
FROM YourTable
),
MaxRanks AS (
SELECT *,
mr = MAX(rnk) OVER (PARTITION BY ID)
FROM DistinctRanks
)
SELECT
ID,
Name,
Count
FROM MaxRanks t
WHERE t.mr > 1;

How to group by one column, aggregate by another column and get another column as result in postgresql?

This seems something simple, but couldn't find an answer for this question last few hours.
I have a table request_state, where "id" is primary key, it can have multiple entries with same state_id. I want to get the id after grouping by state_id using max datetime.
So I tried this, but it gives error "state_id" must appear in the GROUP BY clause or be used in an aggregate function
select id, state_id, max(datetime)
from request_state
group by id
but when I use following query, I get multiple entries with same state_id.
select id, state_id, max(datetime)
from request_state
group by id, state_id
My table:
id state_id date_time
cef 1 Jan 1
ter 1 Jan 2
ijk 1 Jan 3
uuu 2 Feb 1
rrr 2 Feb 2
This is what I want as my result,
id state_id date_time
__ ________ _________
ijk 1 Jan 3
rrr 2 Feb 2
You seem to want:
select max(id) as id, state_id, max(datetime)
from request_state
group by state_id;
If you want the row where datetime is maximum for each state, then use distinct on:
select distinct on (state) rs.*
from request_state rs
order by state, datetime desc;
Try this query:
select id, state_id, date_time from (
select id, state_id, date_time,
row_number() over (partition by state_id order by date_time desc) rn
from tbl
) a where rn = 1
You can use correlated suqbuery :
select t.*
from table t
where date_time = (select max(date_time) from table t1 where t1.state_id = t.state_id);

sql group by and max and other values

i have a table that contains:
itemid inventdimid datephysical transrefid
10001 123 2015-01-02 300002
10002 123 2015-01-03 3566
10001 123 2015-02-05 55555
10002 124 2015-02-01 4545
The result i want
itemid inventdimid datephysical transrefid
10001 123 2015-02-05 555
10002 123 2015-01-03 3566
10002 124 2015-02-01 4545
MY query:
SELECT a.itemid,a.inventdimid,max(a.datephysical),a.transrefid
FROM a where dataareaid = 'ermi'
group by a.itemid,a.inventdimid
it is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Use the ANSI standard row_number() function:
select t.*
from (select t.*,
row_number() over (partition by itemid, inventdimid
order by datephysical desc) as seqnum
from table t
) t
where seqnum = 1;
Find max(a.datephysical) for each itemid, inventdimid combination, select all rows from that date.
SELECT itemid, inventdimid, datephysical, transrefid
FROM a a1
where dataareaid = 'ermi'
and datephysical = (select max(datephysical)
from a a2
where a1.itemid = a2.itemid
and a1.inventdimid = a2.inventdimid
and a2.dataareaid = 'ermi')
You have to create a temporary table with your GROUP BY and then join the original table with it.
Try this:
SELECT T1.*,T2.datephysical,T2.transrefid FROM
(SELECT itemid,inventdimid
FROM TableName
GROUP BY itemid,inventdimid) T1 JOIN
(SELECT itemid,inventdimid,datephysical,transrefid
FROM TableName) T2 ON T1.itemid=T2.itemid AND T1.inventdimid=T2.inventdimid
I'm assuming you want the transrefid corresponding with the a.datephysical shown? This would be done by turning the column into a subquery:
SELECT a.itemid,a.inventdimid,max(a.datephysical),
(SELECT b.transrefid FROM MY_TABLE b where
b.datareaid = 'ermi' and b.itemid = a.itemid and b.inventdimid = a.itemid
and b.datephysical = max(a.datephysical)) as transrefid
FROM MY_TABLE a where dataareaid = 'ermi'
group by a.itemid, a.inventdimid
Some databases may not support this syntax though and it will fail if there are more than one records with the same date.

Return value at max date for a particular id

Here's my sql server table
ID Date Value
___ ____ _____
3241 9/17/12 5
3241 9/16/12 100
3241 9/15/12 20
4355 9/16/12 12
4355 9/15/12 132
4355 9/14/12 4
1234 9/16/12 45
2236 9/15/12 128
2236 9/14/12 323
2002 9/17/12 45
This seems like it should be easy to do, but I don't know why I'm stuck. I'd like to select ONLY the max(date) and value at that max(date) for each id. I want to ignore all other dates that aren't the max(date) with respect to each id.
Here's what I'd like the table to look like:
ID Date Value
___ ____ _____
3241 9/17/12 5
4355 9/16/12 12
1234 9/16/12 45
2236 9/15/12 128
2002 9/17/12 45
I tried group by using max(date), but it didn't group anything. I'm not sure what I'm doing wrong. Thanks in advance for the help!
You can use the following:
select t1.id, t2.mxdate, t1.value
from yourtable t1
inner join
(
select max(date) mxdate, id
from yourtable
group by id
) t2
on t1.id = t2.id
and t1.date = t2.mxdate
See Demo
I have used this for avoiding join statement
WITH table1
AS (SELECT
id,
Date,
Value,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY Date DESC) AS rn
FROM yourtable)
SELECT
*
FROM table1
WHERE rn = 1
This would give you what you need:
SELECT
m.ID,
m.Date,
m.Value
FROM
myTable m
JOIN (SELECT ID, max(Date) as Date FROM myTable GROUP BY ID) as a
ON m.ID = a.ID and m.Date = a.Date
You haven't specified your SQL implementation, but something like this should work:
Note that the op didn't specifically ask to use max(), just to get the id, value at the max[imum] date.
TSQL:
select top 1 ID, Date, Value from yourtable order by Date DESC;
Not TSQL, has to support limit:
(Not tested.)
select ID, Date, Value from yourtable order by Date DESC limit 1,1;

Query SQL distinct field with max date, returning all fields from table

I'm having a hard time trying to get a query that sounds simple. I'm using SQL Server 2008.
I have this table:
ID Name Date Zone
----------------------------
01 AAA 01/01/2010 North
02 BBB 02/02/2010 South
03 AAA 05/01/2010 West
So, I need to filter the table to get distinct items (by Name), but, in case the item is repeated, get the one with the max date. Here is the result that I wanted to get from the example above:
ID Name Date Zone
----------------------------
02 BBB 02/02/2010 South
03 AAA 05/01/2010 West
The problem is that I need to get all the fields from the table (I mean: Id, Name, Date and Zone should be returned from the query) once applied the filter.
Try this:
;WITH CTETable AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY Name ORDER BY [Date] DESC) ID
FROM YourTable
)
SELECT *
FROM CTETable
WHERE ID = 1
select
t.ID,
t.Name,
t.Date,
t.Zone
from
ThisTable t
inner join
(select
Name,
max(Date) as Date
from
ThisTable
group by
Name) x on x.Name = t.Name and x.Date = t.Date
SELECT a.columns
FROM table a
WHERE a.ID IN
(SELECT TOP 1 b.id FROM table b WHERE b.Name = a.Name ORDER BY b.Date DESC)
This will return the most recent row for each unique name.