Saya menggunakan SQL Server 2016 dan data yang saya konsumsi memiliki formulir berikut.
CREATE TABLE #tab (cat CHAR(1), t CHAR(2), val1 INT, val2 CHAR(1));
INSERT INTO #tab VALUES
('A','Q1',2,NULL),('A','Q2',NULL,'P'),('A','Q3',1,NULL),('A','Q3',NULL,NULL),
('B','Q1',5,NULL),('B','Q2',NULL,'P'),('B','Q3',NULL,'C'),('B','Q3',10,NULL);
SELECT *
FROM #tab;
Saya ingin mendapatkan nilai bukan nol terakhir di atas kolom val1
dan val2
dikelompokkan berdasarkan cat
dan dipesan oleh t
. Hasil yang saya cari adalah
cat val1 val2 A 1 P B 10 C
Yang paling dekat yang saya gunakan adalah menggunakan LAST_VALUE
sementara mengabaikan ORDER BY
yang tidak akan berhasil karena saya membutuhkan nilai non-null terakhir yang dipesan.
SELECT DISTINCT
cat,
LAST_VALUE(val1) OVER(PARTITION BY cat ORDER BY (SELECT NULL) ) AS val1,
LAST_VALUE(val2) OVER(PARTITION BY cat ORDER BY (SELECT NULL) ) AS val2
FROM #tab
cat val1 val2 A NULL NULL B 10 NULL
Tabel aktual memiliki lebih banyak kolom untuk cat
( kolom tanggal dan string) dan lebih banyak kolom val (kolom tanggal, string, dan angka) untuk memilih nilai bukan nol terakhir.
Ada ide bagaimana membuat pilihan ini.
sql-server
window-functions
Edmund
sumber
sumber
cat
dipesan oleht
.t
nilainya berulang. Ini adalah data yang tidak berperilaku baik.PARTITION BY cat ORDER BY t, id
sebagai contoh. Jika tidak, permintaan yang sama (permintaan apa pun) dapat memberi Anda hasil yang berbeda pada eksekusi terpisah. Jika kolom dalam tabel hanya yang Anda tampilkan, saya tidak melihat bagaimana kita dapat memiliki pesanan yang pasti!Jawaban:
Menggunakan teknik gabungan dari The Last non NULL Puzzle oleh Itzik Ben Gan akan terlihat seperti ini dengan tabel data dan tipe data kolom Anda.
Cara lain untuk menulis kueri ini yang membagi langkah-langkah menjadi CTE untuk mungkin lebih baik menunjukkan apa yang sedang terjadi. Ini memberikan rencana eksekusi yang sama persis seperti permintaan di atas.
Solusi ini menggunakan fakta bahwa menggabungkan nilai nol dengan sesuatu menghasilkan nilai nol. SET CONCAT_NULL_YIELDS_NULL (Transact-SQL)
sumber
Cukup tambahkan tanda centang untuk NULL di partisi yang akan dilakukan
sumber
Ini harus dilakukan. row_number () dan gabung
Jika Anda tidak memiliki jenis yang baik, Anda harus berharap hanya satu dari Q3 yang tidak nol.
sumber