2013-02-13 5 views
10

これが私のコードです:this page of BOLTSQL:COUNT(*)OVER(ORDER BY句)が

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; 

、Microsoftは述べている:PARTITIONのBYが指定されていない

場合は、関数は、クエリ結果セットのすべての行を単一のグループとして扱います。

私の理解に基づいて、最後の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 

誰もが理由を説明するのに役立つことができますか?ありがとう。

+0

私は間違っているかもしれませんが、COUNT(*)OVER(ORDER BYフィールド)はまったく動作しないと思います... – sgeddes

+0

@bluefeet - これは私が思ったことです - ありがとう... – sgeddes

+0

SQLServer 2012 - http://sqlfiddle.com/#!6/fe2f9/7を参照してください。 –

答えて

28

はランニング合計を与える(この機能は、version 2012までSQL Serverで実装されていなかった。)

ORDER BYが指定されていないデフォルトとしてUNBOUNDED PRECEDINGCURRENT ROWと集約されるウィンドウを定義します。 SQL Serverの既定値はROWSではなくless well performingRANGEです。

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 

あなたは両方PARTITION BYORDER BYを省略取得し、空OVER()節(また、上に示した)を使用することを期待していた結果を達成するために。