TSQL OVER子句:COUNT(*)OVER(ORDER BY a)

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 PRECEDINGCURRENT 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 BYORDER BY和使用空OVER()条款(如上所示).