Reputation: 18958
I need to get all the consecutive top row where a column value is equal between them
my table is:
CREATE TABLE [dbo].[Items](
[Id] [int] NOT NULL,
[IdUser] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[SomeData] nvarchar(50) NOT NULL);
and i want the top rows (ordered by Id
desc) with the same IdUser
if table data is:
Id IdUser CreatedDate SomeData
--- ------- ------------------------ --------
1 1 2017-09-21T09:42:01.407Z sdafsasfa
2 1 2017-09-21T09:42:01.407Z sdafsasfa
4 2 2017-09-21T09:42:01.41Z sdafsasfa
5 3 2017-09-21T09:42:01.41Z sdafsasfa
7 3 2017-09-21T09:42:01.413Z sdafsasfa
8 3 2017-09-21T09:42:01.413Z sdafsasfa
9 10 2017-09-21T09:42:01.417Z sdafsasfa
11 11 2017-09-21T09:42:01.417Z sdafsasfa
12 2 2017-09-21T09:42:01.42Z sdafsasfa
15 2 2017-09-21T09:42:01.42Z sdafsasfa
I want :
Id IdUser CreatedDate SomeData
--- ------- ------------------------ --------
12 2 2017-09-21T09:42:01.42Z sdafsasfa
15 2 2017-09-21T09:42:01.42Z sdafsasfa
if table data is:
Id IdUser CreatedDate SomeData
--- ------- ------------------------ --------
1 1 2017-09-21T09:42:01.407Z sdafsasfa
2 1 2017-09-21T09:42:01.407Z sdafsasfa
4 2 2017-09-21T09:42:01.41Z sdafsasfa
I want :
Id IdUser CreatedDate SomeData
--- ------- ------------------------ --------
4 2 2017-09-21T09:42:01.41Z sdafsasfa
Upvotes: 1
Views: 85
Reputation: 113
select I.*
from
[dbo].[Items1] I
JOIN
(select top 1 Id, IdUser,CreatedDate from [dbo].[Items1] order by Id desc)I2
on I.CreatedDate=I2.CreatedDate
order by Id desc;-- this can be removed to remove ordering by Id Desc
Upvotes: 0
Reputation: 18958
Despite TriV's solution works fine I ended up using a modified Radim Bača's solution (his solution dont work as i need) because it is faster IMO
SELECT id, iduser, createddate, somedata
FROM Items t1
WHERE NOT EXISTS (
SELECT 1
FROM Items t2
WHERE t2.id > t1.id and t2.iduser <> t1.iduser );
Upvotes: 1
Reputation: 10701
Assuming you want last rows with highest CreateDate and same IdUser then DENSE_RANK
will help
SELECT id, iduser, CreatedDate, somedata
FROM (
SELECT id, iduser, CreatedDate, somedata,
DENSE_RANK() OVER (ORDER BY CreatedDate desc, IdUser) ord
FROM [dbo].[Items]) t
WHERE t.ord = 1
The equivalent SQL query is
SELECT *
FROM Items t1
WHERE NOT EXISTS (
SELECT *
FROM Items t2
WHERE t2.createddate > t1.createddate or
(t2.createddate = t1.createddate and t2.iduser < t1.iduser)
)
Upvotes: 1
Reputation: 5148
You could use LAG
and SUM() OVER()
like this
DECLARE @Items as Table
(
[Id] [int] NOT NULL,
[IdUser] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[SomeData] nvarchar(50) NOT NULL
);
INSERT INTO @Items
(
Id,
IdUser,
CreatedDate,
SomeData
)
VALUES
( 1 , 1 ,getdate(),'sdafsasfa'),
( 2 , 1 ,getdate(),'sdafsasfa'),
( 4 , 2 ,getdate(),'sdafsasfa'),
( 5 , 3 ,getdate(),'sdafsasfa'),
( 7 , 3 ,getdate(),'sdafsasfa'),
( 8 , 3 ,getdate(),'sdafsasfa'),
( 9 , 10,getdate(),'sdafsasfa'),
( 11, 11,getdate(),'sdafsasfa'),
( 12, 2 ,getdate(),'sdafsasfa'),
( 15, 2 ,getdate(),'sdafsasfa')
;WITH temp AS
(
SELECT *,
CASE
WHEN lag(i.IdUser) over(ORDER BY i.Id) = i.IdUser THEN 0
ELSE 1
END as ChangingPoint
FROM @Items i
),
temp1 AS
(
SELECT
*,
sum(t.ChangingPoint) OVER(ORDER BY t.Id) as GroupId
FROM temp t
)
SELECT TOP 1 WITH TIES
t.Id,
t.IdUser,
t.CreatedDate,
t.SomeData
FROM temp1 t
ORDER BY GroupId DESC
See demo here: http://rextester.com/PHWWU96232
Upvotes: 1
Reputation: 17126
you can try this query:
select I.*
from
[dbo].[Items] I
JOIN
(select top 1 Id, IdUser from [dbo].[Items] order by Id desc)I2
on I.Iduser=I2.Iduser
order by Id desc;-- this can be removed to remove ordering by Id Desc
Upvotes: 1