Home > Software engineering >  How to compare dates between rows with same column values except one or two columns?
How to compare dates between rows with same column values except one or two columns?

Time:11-30

I have a doubt in logic of SQL query please help me in resolving this.

How to select a row with a earliest posting date for a single invoice number in SQL Server:

Existing table:

INVOICE NUMBER NAME Posting date Place
2050 Dinosaur 20.05.1998 London
2050 Dinosaur 25.04.1995 Australia
2045 Birds 18.03.1997 America
2045 Birds 27.07.1995 China
2075 Lion 12.06.2012 India

I want to query the output like this:

INVOICE NUMBER NAME Posting date Place
2050 Dinosaur 25.04.1995 Australia
2045 Birds 27.07.1995 China
2075 Lion 12.06.2012 India

I am struggling with logic for how to compare dates of two posting date and return the row with lowest posting date column value for each invoice number in SQL Server.

I tried to use MIN() and INNER JOIN before but it didn't help in my complex codebase so I am displaying it in simple manner here.

EDIT: updated from the previous one I want this change to occur only to newly created invoices not already existing ones, so i want to be applied if the invoice date is greater than the a particular date or other way occur only if the invoice number is already existing in database AND also having two posting dates for the same invoice number.

The query should produce a table if the invoice date is not existing in sample database and also having two posting dates then it should display a single row with earliest posting date (having same invoice number) eg :china

if the invoice date is existing in a sample database and having two posting dates then it should display all the rows with same invoice number with no change eg: london, australia

Other rows which have single posting date ( whether they exist or not existing in a sample database) they should display their row. eg:India

Existing Example table:

INVOICE NUMBER NAME Invoice Date Posting date Place
2050 Dinosaur 20.03.1999 20.05.1998 London
2050 Dinosaur 20.03.1999 25.04.1995 Australia
2045 Birds 26.06.2005 18.03.1997 America
2045 Birds 26.06.2005 27.07.1995 China
2075 Lion 22.04.2012 12.06.2012 India

I want to query as single Query to display output like this:

INVOICE NUMBER NAME Invoice Date Posting date Place
2050 Dinosaur 20.03.1999 20.05.1998 London
2050 Dinosaur 20.03.1999 25.04.1995 Australia
2045 Birds 26.06.2005 27.07.1995 China
2075 Lion 22.04.2012 12.06.2012 India

I'm not able to that as a single SELECT query and I also checked with particular date instead of checking in database, it too failed. Please help me on this.

Remark : this is sample table, it will be filled with dynamic values with dynamic columns from codebase, so, ommiting American row is my not expected output, getting output based on the logic is the expected output.

Thank you

CodePudding user response:

The window functions are your friends. Well worth your time to get comfortable with them. Also not clear if you need NAME in the partition by

Also, if you want to see ties ... use dense_rank() instead of row_number()

More Performant

Select *
 From  (
         Select *
               ,RN = row_number() over (partition by InvoiceNumber,Name order by PostingDate)
           From YourTable
       ) A
 Where RN=1

Another Option

Select top 1 with ties *
 From  YourTable 
 Order by row_number() over (partition by InvoiceNumber,Name order by PostingDate)
  • Related