Jus*_*ner 11 sql t-sql sql-server window-functions sql-server-2012
这是我的代码:
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;
Run Code Online (Sandbox Code Playgroud)
在BOL的这个页面上,微软说:
如果未指定PARTITION BY,则该函数将查询结果集的所有行视为单个组.
所以根据我的理解,最后SELECT
一句话会给我以下结果.由于所有记录都被视为一个组,对吧?
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
Run Code Online (Sandbox Code Playgroud)
但实际结果是:
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
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮忙解释原因?谢谢.
Mar*_*ith 30
它提供了一个运行总计(在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;
Run Code Online (Sandbox Code Playgroud)
返回
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
Run Code Online (Sandbox Code Playgroud)
为了实现这一目标你期望得到忽略的结果都将PARTITION BY
和ORDER BY
和使用空OVER()
条款(如上所示).