これは私のコードです:
USE [tempdb];
GO
IF OBJECT_ID(N'dbo.t') IS NOT NULL
BEGIN
DROP TABLE dbo.t
END
GO
CREATE TABLE dbo.t
(
a NVARCHAR(8),
b NVARCHAR(8)
);
GO
INSERT t VALUES ('a', 'b');
INSERT t VALUES ('a', 'b');
INSERT t VALUES ('a', 'b');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('e', NULL);
INSERT t VALUES (NULL, NULL);
INSERT t VALUES (NULL, NULL);
INSERT t VALUES (NULL, NULL);
INSERT t VALUES (NULL, NULL);
GO
SELECT a, b,
COUNT(*) OVER (ORDER BY a)
FROM t;
このBOLのページ では、Microsoftは次のように述べています。
PARTITION BYが指定されていない場合、関数はクエリ結果セットのすべての行を1つのグループとして扱います。
したがって、私の理解に基づくと、最後のSELECT
ステートメントは次の結果をもたらします。すべてのレコードは1つの単一グループと見なされるので、そうですか?
a b
-------- -------- -----------
NULL NULL 12
NULL NULL 12
NULL NULL 12
NULL NULL 12
a b 12
a b 12
a b 12
c d 12
c d 12
c d 12
c d 12
e NULL 12
しかし、実際の結果は次のとおりです。
a b
-------- -------- -----------
NULL NULL 4
NULL NULL 4
NULL NULL 4
NULL NULL 4
a b 7
a b 7
a b 7
c d 11
c d 11
c d 11
c d 11
e NULL 12
誰もが理由を説明するのを手伝ってくれる?ありがとう。
それは現在までの合計を示します(この機能は バージョン2012 になるまでSQL Serverに実装されませんでした。)
_ORDER BY
_は、指定されない場合のデフォルトとして、_UNBOUNDED PRECEDING
_および_CURRENT ROW
_で集約されるウィンドウを定義します。 SQL Serverのデフォルトは、RANGE
ではなく パフォーマンスが低いROWS
オプションです。
RANGE
バージョンのウィンドウには、現在の行(およびその前の行)だけでなく、a
の値が同じである追加の関連付けられた行も含まれるという点で、タイの場合はセマンティクスが異なります。現在の行として。これは、以下の結果の各行でカウントされた行数で確認できます。
_SELECT a,
b,
COUNT(*) OVER (ORDER BY a
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [Rows],
COUNT(*) OVER (ORDER BY a
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [Range],
COUNT(*) OVER() AS [Over()]
FROM t;
_
戻り値
_a b Rows Range Over()
-------- -------- ----------- ----------- -----------
NULL NULL 1 4 12
NULL NULL 2 4 12
NULL NULL 3 4 12
NULL NULL 4 4 12
a b 5 7 12
a b 6 7 12
a b 7 7 12
c d 8 11 12
c d 9 11 12
c d 10 11 12
c d 11 11 12
e NULL 12 12 12
_
あなたが除外することを期待していた結果を達成するためにboth_PARTITION BY
_および_ORDER BY
_を使用し、空のOVER()
句(上記にも示されています)。