2014-06-21 9 views

Antwort

0

Oracle 11 unterstützt die Option ignore nulls, die genau das tut, was Sie wollen. Natürlich geht es bei Ihrer Frage um SQL Server, aber manchmal ist es ermutigend zu wissen, dass die Funktionalität irgendwo existiert.

Es ist möglich, diese Funktionalität zu simulieren. Die Idee besteht darin, basierend auf dem vorhergehenden Wert Nullwerte einer Gruppe zuzuweisen. Im Wesentlichen zählt dies die Anzahl der Nicht-Null-Werte davor. Sie können dies mit einer korrelierten Unterabfrage tun. Oder interessanterweise mit dem Unterschied zweier Zeilennummern. Dann können Sie innerhalb der Gruppe einfach max() verwenden.

Ich denke, das Folgende macht was Sie wollen. Es sei angenommen, dass colNULL Werte enthält und ordering hat die Reihenfolge für die Zeilen:

select t.*, 
     max(col) over (partition by grp) as LagOnNull 
from (select t.*, 
      (row_number() over (order by ordering) - 
       row_number() over (partition by col order by ordering) 
      ) as grp 
     from table t 
    ) t; 

Die lead() ist ähnlich, aber die Reihenfolge umgekehrt ist. Und dies funktioniert mit zusätzlichen Partitionierungsschlüsseln, aber Sie müssen sie zu allen Fensterausdrücken hinzufügen.

+0

Danke für Ihre Antwort Gordon. Aber ich kann nicht verstehen, was Col2 in diesem Beispiel ist? – Mostapha777

+0

'col2' sollte' col' sein, das Argument zu 'lag()'/'lead()'. –

+0

Kreative Lösung Gordon. Aber leider hat es bei mir nicht funktioniert :( – Mostapha777

2

Es ist möglich, Fensterfunktionen zu verwenden. Lesen Sie diese article von Itzik Ben-Gan für weitere Details.

Im folgenden Code erhält die CTE den neuesten NOT NULL ID-Wert, dann erhält die nächste Auswahl den tatsächlichen Spaltenwert. In diesem Beispiel wird LAG verwendet. z.

-- DDL for T1 
SET NOCOUNT ON; 
USE tempdb; 
IF OBJECT_ID(N'dbo.T1', N'U') IS NOT NULL DROP TABLE dbo.T1; 
GO 
CREATE TABLE dbo.T1 
(
id INT NOT NULL CONSTRAINT PK_T1 PRIMARY KEY, 
col1 INT NULL 
); 

-- Small set of sample data 
TRUNCATE TABLE dbo.T1; 

INSERT INTO dbo.T1(id, col1) VALUES 
(2, NULL), 
(3, 10), 
(5, -1), 
(7, NULL), 
(11, NULL), 
(13, -12), 
(17, NULL), 
(19, NULL), 
(23, 1759); 

;WITH C AS 
(
SELECT 
    id, 
    col1, 
    MAX(CASE WHEN col1 IS NOT NULL THEN id END) OVER(ORDER BY id ROWS UNBOUNDED PRECEDING) AS grp 
FROM dbo.T1 
) 
SELECT 
    id, 
    col1, 
    (SELECT col1 FROM dbo.T1 WHERE id = grp) lastval  
FROM C; 
Verwandte Themen