当前位置: 首页 > 面试题库 >

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

左丘恩
2023-03-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的此页面上,Microsoft说:

如果未指定PARTITION BY,则该html" target="_blank">函数会将查询结果集的所有行都视为一个组。

因此,根据我的理解,最后的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

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


问题答案:

它给出了一个正在运行的总数(此功能直到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;

退货

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()条款(如上所示)。



 类似资料:
  • 问题内容: 我正在为FAQ列表编写一些非常简单的搜索功能。我正在将搜索字符串拆分为各种字符,包括空格。然后根据以下内容执行选择 我不得不对其进行稍微的编辑,使其由我们的数据访问层生成,但是它应该使您对发生的事情有所了解。 上面的查询很好地说明了这个问题,因为大多数问题中可能都包含单词a或is,但是我无法将其过滤掉,因为首字母缩略词对搜索者而言很重要。建议的是,我们根据匹配关键字的数量进行排序。但是

  • 问题内容: 使over子句在mysql中工作的正确语法是什么? 我想查看每个用户发送的短信总数,而不用group by子句将其分组。 问题答案: 据我所知,MySQL中没有OVER子句,但是以下链接可以帮助您实现相同的结果: http://explainextended.com/2009/03/10/analytic-functions-first_value- last_value-lead-l

  • 问题内容: 我试图弄清楚如何在MySQL中优化一个非常慢的查询(我没有设计这个): 比较一下: 说明语句对我没有帮助: 好的,它仍然认为它需要大约400万个条目才能计数,但是我可以计算文件中的行数比这还要快!我不明白为什么MySQL要花这么长时间。 这是表的定义: 版: 有什么明显的我想念的东西吗?(是的,我已经尝试过“ SELECT COUNT(change_event_id)”,但是没有性能差

  • 问题内容: 这是我表中的列: 我想删除重复的行,这些行中的和是相同的-只是为了澄清- 我确实想保留其中之一。我认为我应该将子句与一起使用,但不确定。 谢谢 问题答案: 如果要保留重复组中的一行,可以使用。在这个例子中,我保持最低的行:

  • #美团暑期[话题]# 分享一下时间线 3.16 笔试 3.25 一面 基础研发平台 3.28 进入人才库 —————— 4.11 开启第二志愿 一面 优选部门 4.15 二面 4.19 oc+offer 感谢自己这两个月没有放弃吧 也感谢团子给了我这次机会 #暑期实习转正# #暑期前端# #美团暑期# 另外有5月下旬去北京租房的友友可联系一下哟