2014-06-21 11 views

risposta

0

Oracle 11 supporta l'opzione ignore nulls che fa esattamente ciò che si desidera. Naturalmente, la tua domanda riguarda SQL Server, ma a volte è incoraggiante sapere che la funzionalità esiste da qualche parte.

È possibile simulare questa funzionalità. L'idea è di assegnare valori nulli a un gruppo, in base al valore precedente. In sostanza, questo è il conteggio del numero di valori non nulli prima di esso. Puoi farlo con una sottoquery correlata. O, più interessante, con la differenza di due numeri di riga. Quindi all'interno del gruppo, puoi semplicemente usare max().

Penso che quanto segue fa quello che vuoi. Si supponga che col contiene NULL valori e ordering ha l'ordinamento per le righe:

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; 

Il lead() è simile, ma l'ordine è invertito. E ciò funzionerà con chiavi di partizionamento aggiuntive, ma è necessario aggiungerle a tutte le espressioni della finestra.

+0

Grazie per la risposta, Gordon. Ma non riesco a capire cosa c'è "col2" in questo esempio? – Mostapha777

+0

'col2' avrebbe dovuto essere' col', l'argomento di 'lag()'/'lead()'. –

+0

Soluzione creativa Gordon. Ma sfortunatamente non ha funzionato per me :( – Mostapha777

2

È possibile utilizzare le funzioni della finestra. Leggi questo article di Itzik Ben-Gan per maggiori dettagli.

Nel codice seguente, il cte sta ottenendo il valore di identificazione NOT NULL più recente, quindi la selezione successiva ottiene il valore di colonna effettivo. Questo esempio utilizza LAG. es.

-- 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; 
Problemi correlati