Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use ROW_NUMBER() OVER/PARTITION BY only when another column is also the same?

I am using this code: (from this question: How to get the last record per group in SQL substituting my own columns)

WITH e AS
(
 SELECT *,
     ROW_NUMBER() OVER
     (
         PARTITION BY ApplicationId
         ORDER BY theDate DESC
     ) AS Recency
 FROM [Event]
)
SELECT *
FROM e
WHERE Recency = 1

Is it possible to 'partition' only if two fields are the same? For example I have data like this:

ID      Name    theDate
123     John    01/01/2012
123     John    01/02/2012
123     Doe     01/01/2012
456     Smith   02/04/2012
789     Smith   02/01/2012
789     Smith   02/09/2012
789     Roger   02/08/2012

From that data I'd want to return:

ID      Name    theDate
123     John    01/02/2012
123     Doe     01/01/2012
456     Smith   02/04/2012
789     Smith   02/09/2012
789     Roger   02/08/2012

Thanks for any help.

Thomas

like image 582
tsdexter Avatar asked Apr 18 '12 01:04

tsdexter


People also ask

Can we use ROW_NUMBER without partition by?

ROW_NUMBER() Function without Partition By clausePartition by clause is an optional part of Row_Number function and if you don't use it all the records of the result-set will be considered as a part of single record group or a single partition and then ranking functions are applied.

What does ROW_NUMBER () over partition by do?

The ROW_NUMBER() function uses the OVER and PARTITION BY clause and sorts results in ascending or descending order. It starts ranking rows from 1 per the sorting order.

Can we use ROW_NUMBER without over?

The row_number() window function can be used without order by in over to arbitrarily assign a unique value to each row.

Does ROW_NUMBER require ORDER BY?

Because the ROW_NUMBER function requires an ORDER BY clause, the ROW_NUMBER function specifies ORDER BY (SELECT 1) to return the rows in the order in which they are stored in the specified table and sequentially number them, starting from 1.


2 Answers

You can have several columns separated by a comma

WITH e AS 
( 
 SELECT *, 
     ROW_NUMBER() OVER 
     ( 
         PARTITION BY ApplicationId , Name
         ORDER BY theDate DESC 
     ) AS Recency 
 FROM [Event] 
) 
SELECT * 
FROM e 
WHERE Recency = 1 
like image 66
JeffO Avatar answered Oct 07 '22 01:10

JeffO


I've found it the answer here: Table partitioning using 2 columns

You can only partition on 1 column, however that column can be generated to make a 'multiple partition' like so:

WITH e AS 
( 
 SELECT *, 
 ROW_NUMBER() OVER 
 ( 
     PARTITION BY CONVERT(VARCHAR(100),ApplicationId) + ' ' + Name
     ORDER BY theDate DESC 
 ) AS Recency 
 FROM [Event] 
) 
SELECT * 
FROM e 
WHERE Recency = 1 

Adding the two columns together as one single string ensures it will only partition if both columns are identical.

like image 45
tsdexter Avatar answered Oct 07 '22 01:10

tsdexter