2016-09-23 5 views
1

この動作は非常に奇妙で直観的ではありません。 (SQLの場合でも)。ヌルのすべての行数を計算する目的のために同じグループの一部として扱われていることを意味するSQL Server - Null値によるROW_NUMBERパーティションの動作

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

を返し

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 

。 SET ANSI_NULLLSがオンかオフかは関係ありません。 しかし、定義上、ヌルは全く知られていないので、このようにヌルをどのようにグループ化できますか?リンゴやオレンジ、マイナス1の平方根、クオンタムブラックホールなど、意味のある順序で物事を並べるためには、少しの実験では、最初の列がランクオーダーを生成するために使用されていることが示唆されています。

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

は同じ値を生成します。これは、私が扱っているレガシーコードに問題を引き起こした重要な意味を持っています。これは予期された動作ですか、選択クエリのnullを一意の値に置き換える以外にも、それを緩和する方法はありますか?

私が期待した結果がDENSE_RANKを(使用

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

されているだろうが)違いはありません。

+0

'PARTITIONのBY'グループを構築するには、それは一貫していませんか? 'GROUP BY'はSQL:2003標準で文書化されたものと同じです。 [Read](https://technet.microsoft.com/en-us/library/ms187007(v = sql.90).aspx) –

+0

読みます。しかし、グループにはグループ内に固有の順序はありません。パーティションはそのような順序を作成します。そのようなものは根本的に異なります – SimonN

答えて

0

ヨ。

T-SQLが述語でNULLを扱うとき、それは三項論理(TRUE、FALSEまたはUNKNOWN)を使用し、クエリから期待した動作を表示します。ただし、値をグループ化する場合、T-SQLはNULLを1つのグループとして扱います。したがって、クエリはNULLをグループ化し、そのウィンドウ内の行の番号付けを開始します。あなたが見たい、このクエリは動作するはずと言う結果を得るために

...

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 
関連する問題