2016-09-23 2 views
1

Ich finde dieses Verhalten sehr seltsam und kontraintuitiv. (Auch für SQL).SQL Server - Verhalten von ROW_NUMBER Partition von Null Wert

set ansi_nulls off 
go 
;with sampledata(Value, CanBeNull) as 
(
    select 1, 1 
    union 
    select 2, 2 
    union 
    select 3, null 
    union 
    select 4, null 
    union 
    select 5, null 
    union 
    select 6, null 
) 
select ROW_NUMBER() over(partition by CanBeNull order by  value) 'RowNumber',* from sampledata 

Welche

1 3 NULL 
2 4 NULL 
3 5 NULL 
4 6 NULL 
1 1 1 
1 2 2 

kehrt was bedeutet, dass alle der nulls als Teil der gleichen Gruppe für die Zwecke der Berechnung der Zeilennummer behandelt werden. Es spielt keine Rolle, ob SET ANSI_NULLLS aktiviert oder deaktiviert ist. Da aber definitionsgemäß die Null völlig unbekannt ist, wie können die Nullen so gruppiert werden? Es wird gesagt, dass für die Zwecke der Platzierung von Dingen in einer Rangordnung, dass Äpfel und Orangen und die Quadratwurzel von minus 1 und quantum black holes oder was auch immer sinnvoll geordnet werden kann. Etwas Experimentieren legt nahe, daß die erste Spalte verwendet wird, um den Rang als

select 1, '1' 
    union 
    select 2, '2' 
    union 
    select 5, null 
    union 
    select 6, null 
    union 
    select 3, null 
    union 
    select 4, null 

erzeugt die gleichen Werte zu erzeugen. Dies hat erhebliche Auswirkungen, die zu Problemen mit Legacy-Code geführt haben, mit dem ich mich beschäftige. Ist dies das erwartete Verhalten und gibt es eine andere Möglichkeit, es zu mildern, als das NULL in der SELECT-Abfrage durch einen eindeutigen Wert zu ersetzen?

Die Ergebnisse Ich hätte erwartet hätte

gewesen
1 3 NULL 
1 4 NULL 
1 5 NULL 
1 6 NULL 
1 1 1 
1 2 2 

Mit DENSE_RANK() macht keinen Unterschied.

+0

'PARTITION BY' Gruppen, ist so nicht im Einklang es? 'GROUP BY' macht dasselbe, was im SQL: 2003-Standard dokumentiert ist. [Lesen] (https://technet.microsoft.com/en-us/library/ms187007 (v = sql.90) .aspx) –

+0

Lesen Sie es. Aber eine Gruppe hat keine inhärente Ordnung innerhalb der Gruppe - Partition schafft eine solche Ordnung und unterscheidet sich grundlegend von ihr – SimonN

Antwort

0

Yo.

Also ist das Problem, wenn T-SQL NULL in Prädikaten behandelt, es verwendet ternäre Logik (TRUE, FALSE oder UNKNOWN) und zeigt das Verhalten an, das Sie von Ihrer Abfrage erwarten. Wenn es jedoch um das Gruppieren von Werten geht, behandelt T-SQL NULL als eine Gruppe. Ihre Abfrage gruppiert die NULL-Werte zusammen und beginnt, die Zeilen in diesem Fenster zu nummerieren.

Für die Ergebnisse, die Sie sagen, dass Sie diese Abfrage sehen möchte, sollte ... arbeiten baut

WITH sampledata (Value, CanBeNull) 
AS 
(
    SELECT 1, 1 
    UNION 
    SELECT 2, 2 
    UNION 
    SELECT 3, NULL 
    UNION 
    SELECT 4, NULL 
    UNION 
    SELECT 5, NULL 
    UNION 
    SELECT 6, NULL 
) 
SELECT 
    DENSE_RANK() OVER (PARTITION BY CanBeNull ORDER BY CASE WHEN CanBeNull IS NOT NULL THEN value END ASC) as RowNumber 
    ,Value 
    ,CanBeNull 
FROM sampledata 
Verwandte Themen