Korzystam z programu SQL Server 2016, a dane, które konsumuję, mają następującą postać.
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;
Chciałbym uzyskać ostatnie wartości inne niż null nad kolumnami val1
i val2
pogrupowane według cat
i uporządkowane według t
. Wynik, którego szukam jest
cat val1 val2 A 1 P B 10 C
Najbliższe, które przyszedłem, używa LAST_VALUE
, ignorując to, ORDER BY
co nie zadziała, ponieważ potrzebuję uporządkowanej ostatniej wartości innej niż null.
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
Rzeczywista tabela zawiera więcej kolumn cat
( kolumny daty i łańcucha) i więcej kolumn val (kolumny daty, łańcucha i liczb), aby wybrać ostatnią wartość inną niż null.
Wszelkie pomysły, jak dokonać tego wyboru.
sql-server
window-functions
Edmund
źródło
źródło
cat
wedługt
.t
wartości się powtarzają. Dane nie są dobrze wychowane.PARTITION BY cat ORDER BY t, id
na przykład. W przeciwnym razie to samo zapytanie (dowolne zapytanie) może dać różne wyniki dla poszczególnych wykonań. Jeśli kolumny w tabeli są tylko tymi, które wyświetlasz, nie widzę jednak, jak możemy mieć określoną kolejność!Odpowiedzi:
Przy użyciu techniki konkatenacji z The Last non NULL Puzzle autorstwa Itzika Bena Gana wyglądałoby to tak samo z przykładowymi typami tabel i kolumn.
Inny sposób napisania tego zapytania, który dzieli kroki na CTE, aby być może lepiej pokazać, co się dzieje. Daje dokładnie taki sam plan wykonania jak powyższe zapytanie.
To rozwiązanie wykorzystuje fakt, że konkatenacja wartości null z czymś skutkuje wartością null. ZESTAW CONCAT_NULL_YIELDS_NULL (Transact-SQL)
źródło
Wystarczy dodać sprawdzenie, czy NULL na partycji zrobi
źródło
To powinno to zrobić. row_number () i łączyć
Jeśli nie masz dobrego rodzaju, musisz mieć nadzieję, że tylko jeden z Q3 nie ma wartości zerowej.
źródło