Mengembalikan set hasil dengan beberapa baris berdasarkan tanggal maks

16

Saya punya meja anak yang kira-kira seperti ini:

[Tabel Tanggal Cust]

| Customer ID | Some Date  | Balance |
+-------------+------------+---------+
|           1 | 2012-04-30 |   20.00 |
|           1 | 2012-03-31 |   50.00 |
|           2 | 2012-04-30 |    0.00 |
|           2 | 2012-03-31 |   10.00 | 
|           3 | 2012-03-31 |   60.00 |
|           3 | 2012-02-29 |   10.00 |

Saya ingin dapat memperoleh hasil yang ditetapkan seperti ini - satu catatan untuk setiap klien dengan tanggal terbaru:

| Customer ID | Some Date  | Balance |
+-------------+------------+---------+
|           1 | 2012-04-30 |   20.00 | 
|           2 | 2012-04-30 |    0.00 |
|           3 | 2012-03-31 |   60.00 |

Saya tahu bahwa saya dapat melakukan ini untuk setiap "ID Pelanggan" individu dengan SQL berikut (sintaks SQL Server):

select top 1  [Some Date], [Customer ID], [Balance]
from [Cust Date Table]
where [Customer ID] = 2
order by [Some Date] desc


| Customer ID | Some Date  | Balance |
+-------------+------------+---------+
|           2 | 2012-04-30 |    0.00 |

Tetapi saya tidak yakin bagaimana mendapatkan ketiga catatan yang saya inginkan. Saya tidak yakin apakah ini adalah situasi yang membutuhkan sub-permintaan atau sesuatu yang lain.

Harap perhatikan bahwa tanggal maks dapat berbeda untuk [ID Pelanggan] yang diberikan, (dalam contoh ini, tanggal maksimum pelanggan 3 adalah 2012-03-31 sedangkan catatan lain memiliki tanggal maks 2012-04-30). saya telah mencoba

select [Customer ID], MAX([Some Date]) AS [Latest Date], Balance 
from [Cust Date Table] 
group by [Customer ID], Balance; 

Masalahnya adalah ini tidak hanya mengembalikan satu baris untuk setiap pelanggan - ini mengembalikan beberapa baris.

Joe DBA
sumber

Jawaban:

18

Anda hanya ingin:

SELECT
    [Customer ID],
    MAX([Some Date]) AS[Latest Date]
FROM[Cust Date TABLE]
GROUP BY
    [Customer ID];

Oke - Anda telah merevisinya. Anda sekarang ingin memesan baris dan memilih yang teratas:

WITH numbered AS (
    SELECT
        [Customer ID],
        [Some Date],
        [Balance],
        ROW_NUMBER() OVER (
            PARTITION BY
                [Customer ID]
            ORDER BY
                [Some Date] DESC
        ) AS rownum
    FROM[Cust Date TABLE]
)
SELECT
    [Customer ID],
    [Some Date],
    [Balance]
FROM numbered
WHERE
    rownum = 1;
Rob Farley
sumber
Oh - Anda sudah mengubah pertanyaan?
Rob Farley
Mengubah jawaban saya sekarang.
Rob Farley
Satu keuntungan (atau kerugian, tergantung pada kebutuhan Anda) dari solusi ini adalah bahwa jika tanggal terbaru terjadi lebih dari satu baris untuk pelanggan yang sama, itu tidak akan menghasilkan hasil duplikat.
Tim
7

Saya pikir Anda mencari sesuatu seperti ini

select c.[customer ID], [some date], balance
from [cust date table] c
inner join 
    ( select [customer ID], MAX([some date]) as maxdate
    from [cust date table]
    group by [customer ID]) c2
on c2.[customer ID] = c.[customer ID]
and c2.maxdate = c.[some date]

Ada beberapa variasi dalam hal ini, yaitu CTE, variabel tabel, #tabel, yang dapat Anda mainkan untuk melihat apa yang memberi Anda kinerja terbaik dalam situasi Anda.

WT_W
sumber
Jawaban ini juga benar. Sayangnya saya tidak punya cukup perwakilan untuk meningkatkannya dan saya harus memilih satu jawaban.
Joe DBA