Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSSQL: Only last entry in GROUP BY (with id)

Following / copying computhomas's question, but adding some twists...

I have the following table in MSSQL2008

id | business_key | result | date
1 | 1 | 0 | 9
2 | 1 | 1 | 8
3 | 2 | 1 | 7
4 | 3 | n | 6
5 | 4 | 1 | 5
6 | 4 | 0 | 4

And now i want to group based on the business_key returning the complete entry with the newest date. So my expected result is:

id | business_key | result | date
1 | 1 | 0 | 9
3 | 2 | 1 | 7
4 | 3 | n | 6
5 | 4 | 1 | 5

I also bet that there is a way to achieve that, i just can't find / see / think of it at the moment.

edit: sorry about this, I actually meant something else from original question I did. I felt like editing this might be better than accepting a solution and making another question. my original problem was that I am not filtering by id.

like image 748
cregox Avatar asked Sep 27 '10 14:09

cregox


People also ask

How to retrieve last record for each group in SQL Server?

Retrieve Last Record for each Group in SQL Server Example 1 First, partition the data by Occupation and assign the rank number using the yearly income. Next, it is going to select the last record from each SQL Server group.

How to select first row in each SQL GROUP BY group?

-- Select First Row in each SQL Group By group USE [SQL Tutorial] GO SELECT * FROM ( SELECT [FirstName] , [LastName] , [Education] , [Occupation] , [YearlyIncome] ,ROW_NUMBER () OVER ( PARTITION BY [Occupation] ORDER BY [YearlyIncome] DESC ) AS [ROW NUMBER] FROM [Customers] ) groups WHERE groups.

How to get the last event for each account in PostgreSQL?

The plain SQL solution is to divide and conquer. We already have a query to get the current balance of an account. If we write another query to get the credit for each account, we can join the two together and get the complete state of an account. To get the last event for each account in PostgreSQL we can use DISTINCT ON:

How do you use group by in SQL without aggregate?

SQL GROUP BY and DISTINCT If you use the GROUP BY clause without an aggregate function, the GROUP BY clause behaves like the DISTINCT operator. The following gets the phone numbers of employees and also group rows by the phone numbers. SELECT phone_number FROM employees GROUP BY phone_number;


Video Answer


4 Answers

SELECT t.*
FROM
(
    SELECT *, ROW_NUMBER() OVER
              (
                  PARTITION BY [business_key]
                  ORDER BY [date] DESC
              ) AS [RowNum]
    FROM yourTable
) AS t
WHERE t.[RowNum] = 1
like image 97
LukeH Avatar answered Oct 19 '22 23:10

LukeH


SELECT 
       *
FROM 
       mytable 
WHERE 
       ID IN (SELECT MAX(ID) FROM mytable GROUP BY business_key)
like image 3
CristiC Avatar answered Oct 19 '22 23:10

CristiC


SELECT 
     MAX(T1.id) AS [id],
     T1.business_key, 
     T1.result 
FROM 
     dbo.My_Table T1 
LEFT OUTER JOIN dbo.My_Table T2 ON 
     T2.business_key = T1.business_key AND 
     T2.id > T1.id 
WHERE 
     T2.id IS NULL 
GROUP BY T1.business_key, 
     T1.result 
ORDER BY MAX(T1.id)

Edited based on clarifications

SELECT M1.*
FROM My_Table M1
INNER JOIN 
(
    SELECT [business_key], MAX([date]) as MaxDate
    FROM My_Table 
    GROUP BY [business_key]
) M2 ON M1.business_key = M2.business_key AND M1.[date] = M2.MaxDate
ORDER BY M1.[id]
like image 2
LittleBobbyTables - Au Revoir Avatar answered Oct 20 '22 01:10

LittleBobbyTables - Au Revoir


Assuming the combination of business_key & date is unique then....

Working example (3rd time is a charm):

declare @src as table(id int, business_key int,result int,[date] int)
insert into @src
SELECT 1,1,0,9
UNION SELECT 2,1,1,8
UNION SELECT 3,2,1,7
UNION SELECT 4,3,1,6
UNION SELECT 5,4,1,5
UNION SELECT 6,4,0,4

;with bkdate(business_key,[date])
AS
(
    select business_key,MAX([date])
    from @src 
    group by business_key
)
select src.* from @src src 
inner join bkdate
ON src.[date] = bkdate.date
and src.business_key = bkdate.business_key
order by id
like image 2
Jamiec Avatar answered Oct 19 '22 23:10

Jamiec