Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak uzyskać rekord z Max (data), a następnie porównać wartości, aby uzyskać wynik?

Jest to proces składający się z 3 kroków. Najpierw uszereguj swoje rekordy dla każdej kombinacji Konto/Licznik za pomocą ROW_NUMBER()

SELECT *,
      RowNumber = ROW_NUMBER() OVER(PARTITION BY AccountNumber, MeterNumber 
                                    ORDER BY EndDate DESC)
FROM Meter

WYJŚCIE

AccountNumber MeterNumber Data rozpoczęcia Data zakończenia RateCode RowNumber
0142628117 123470203 2020-04-22 9999-12-31 ETF0_APR20 1
0142628117 123470203 2019-04-10 2020-04-09 ***Niestandardowy*** 2
0142628117 123470205 2020-04-22 9999-12-31 ETF0_APR20 1
0142628117 123470205 2019-04-10 2020-04-09 ***Niestandardowy*** 2
1363445 105238304 2018-10-02 2019-08-11 ***Niestandardowy*** 1
1363445 105238304 25.02.2016 22.04.2016 ***Niestandardowy*** 2
1363445 130359929 2019-08-12 9999-12-31 ***Niestandardowy*** 1

Uwaga Niektóre dane zostały skrócone, aby lepiej się wyświetlać

Następnie możesz filtrować według wartości RowNumber =1, aby uzyskać najnowszą datę zakończenia dla każdego licznika.

Następnie musisz policzyć różne kombinacje EndDate/RateCode, nie możesz użyć COUNT(DISTINCT ...) w funkcji okienkowej, jednak można to emulować za pomocą DENSE_RANK() :

SELECT *,
        CntDistinct = DENSE_RANK() OVER(PARTITION BY AccountNumber 
                                                ORDER BY EndDate, RateCode) 
                        + DENSE_RANK() OVER(PARTITION BY AccountNumber 
                                            ORDER BY EndDate DESC, RateCode DESC) - 1
FROM (  SELECT *,
                RowNumber = ROW_NUMBER() OVER(PARTITION BY AccountNumber, MeterNumber 
                                                ORDER BY EndDate DESC)
        FROM Meter AS m
    ) AS m
WHERE m.RowNumber = 1;

WYJŚCIE

AccountNumber MeterNumber Data rozpoczęcia Data zakończenia RateCode CntDistinct
0142628117 123470203 2020-04-22 9999-12-31 ETF0_APR20 1
0142628117 123470205 2020-04-22 9999-12-31 ETF0_APR20 1
1363445 130359929 2019-08-12 9999-12-31 ***Niestandardowy*** 2
1363445 105238304 2018-10-02 2019-08-11 ***Niestandardowy*** 2

Uwaga Niektóre dane zostały skrócone, aby lepiej się wyświetlać

Na koniec umieść to wszystko w kolejnym podzapytaniu i ogranicz do więcej niż jednej unikalnej kombinacji EndDate/RateCode:

SELECT AccountNumber, MeterNumber, StartDate, EndDate, RateCode
FROM (  SELECT *,
                CntDistinct = DENSE_RANK() OVER(PARTITION BY AccountNumber 
                                                    ORDER BY EndDate, RateCode) 
                                + DENSE_RANK() OVER(PARTITION BY AccountNumber 
                                                    ORDER BY EndDate DESC, RateCode DESC) - 1
            FROM (  SELECT *,
                            RowNumber = ROW_NUMBER() OVER(PARTITION BY AccountNumber, MeterNumber 
                                                        ORDER BY EndDate DESC)
                    FROM Meter AS m
                ) AS m
            WHERE m.RowNumber = 1
    ) AS m
WHERE m.CntDistinct > 1;

WYJŚCIE

AccountNumber MeterNumber Data rozpoczęcia Data zakończenia RateCode
050000178767001363445 TCA105238304 2018-10-02 2019-08-11 ***Niestandardowy***
050000178767001363445 TCA130359929 2019-08-12 9999-12-31 ***Niestandardowy***

Przykład na db<>Skrzypce




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przechowywanie komunikatu raiserror z SqlServer w C#

  2. Ostatnio wstawiony identyfikator MS SQL Server

  3. Pobieranie liczby i wierszy w tym samym zapytaniu

  4. Jak usunąć wiodące i końcowe białe znaki w SQL Server — TRIM()

  5. Nie wyświetlaj pustych zestawów zwrotów