14

这是我的代码:

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 的这个页面上,微软说:

如果未指定 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

但实际结果是:

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

任何人都可以帮助解释为什么?谢谢。

4

2 回答 2

35

它给出了一个运行总数(此功能直到版本 2012才在 SQL Server 中实现。)

ORDER BY定义要聚合的窗口,并且UNBOUNDED PRECEDINGCURRENT ROW未指定时作为默认值。SQL Server 默认使用性能较差的 RANGE选项,而不是ROWS.

它们在 tie 的情况下具有不同的语义,因为RANGE版本的窗口不仅包括当前行(和前面的行),还包括与当前行具有相同 value 的任何其他已绑定行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

要实现您期望得到的结果,请省略and并使用空子句(如上所示)。PARTITION BYORDER BYOVER()

于 2013-02-13T18:22:42.440 回答
1

如果没有指定ROWS/RANGE,但指定了ORDER BY,则RANGE UNBOUNDED PRECEDING AND CURRENT ROW作为窗口框架的默认值那么这是什么意思,让我们关注“UNBOUNDED PRECEDING AND CURRENT ROW”。这给出了从起始行到当前行的运行总计。但如果你想有一个总体计数,那么你也可以指定

“UNBOUNDED PRECEDING 和 UNBOUNDED Follow” 这考虑了整个数据集,而 Over() 只是这个的捷径

    select a,b,
count(*) over(order by a) as [count],
COUNT(*) OVER (ORDER BY a 
                         RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [Range],
COUNT(*) OVER (ORDER BY a 
                         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS  [Rows],
COUNT(*) OVER (ORDER BY a 
                         RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED Following) AS [Range_Unbounded_following],
COUNT(*) OVER (ORDER BY a 
                         ROWs BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED Following) AS [Row_Unbounded_following]
,COUNT(*) OVER () AS [Plain_over]
from t 
order by [count]

结果是

a        b        count       Range       Rows        Range_Unbounded_following Row_Unbounded_following Plain_over
-------- -------- ----------- ----------- ----------- ------------------------- ----------------------- -----------
NULL     NULL     4           4           1           12                        12                      12
NULL     NULL     4           4           2           12                        12                      12
NULL     NULL     4           4           3           12                        12                      12
NULL     NULL     4           4           4           12                        12                      12
a        b        7           7           5           12                        12                      12
a        b        7           7           6           12                        12                      12
a        b        7           7           7           12                        12                      12
c        d        11          11          8           12                        12                      12
c        d        11          11          9           12                        12                      12
c        d        11          11          10          12                        12                      12
c        d        11          11          11          12                        12                      12
e        NULL     12          12          12          12                        12                      12
于 2020-08-19T11:53:58.733 回答