|
这是我的代码:
: l# b- |) t6 p* @/ o% J8 H1 l5 xUSE [tempdb];GOIF OBJECT_ID(N'dbo.t') IS NOT NULLBEGIN DROP TABLE dbo.tENDGOCREATE TABLE dbo.t( a NVARCHAR(8), b NVARCHAR(8));GOINSERT 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);GOSELECT a,b, COUNT(*) OVER (ORDER BY a)FROM t;在BOL在这个页面上,Microsoft说:$ s5 S# O' c. ~3 ~" b3 ]. h
如果未指定PARTITION BY,该函数将查询结果集的所有行视为一个组。- ^' q2 N( i" B8 d- g# |, g) _; ^
所以,根据我的理解,最后SELECT陈述会给我以下结果。因为所有的记录都被视为一个小组,对吗?2 ^, ] h3 t1 Q0 w! x- f2 ^
a b -------- -------- -----------NULL NULL 12NULL NULL 12NULL NULL 12NULL NULL 12a b a b a b c d c d c d c d e NULL 12但实际结果如下:
1 y) U5 |* ^, H. b% i! u* Ka b -------- -------- -----------NULL NULL 4NULL NULL 4NULL NULL 4NULL NULL 4a b 7a b 7a b 7c d c d c d c d e NULL 12任何人都能帮忙解释为什么?
' N, J1 E. v, P8 \) k $ x/ k7 l( u0 |3 ~" Y$ ^
解决方案:
+ y, g) Q7 W; \( ~9 C: R 它给出了一个正在运行的总数(该功能直到2012年才出现SQL Server中实现。)
! G! Q4 V% n, `& {! f在ORDER BY定义窗口和聚合物UNBOUNDED PRECEDING和CURRENT ROW作为未指定时的缺省值。SQL
+ q! L& d; P2 p2 KServer 默认使用性能差RANGE而非ROWS。
1 E) P' p& q2 U( J8 H6 I因为这种关系有不同的语义RANGE版本的窗口不仅包括当前行(和以前行),还包括任何其他与当前行相同值的绑定行a。在下面的结果中,每一行所计数的行数可以看出这一点。( N% y" m. r# r! O
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;退货, s5 s" V% ]% {- N. S) h$ G2 a
a b Rows Range Over()-------- -------- ----------- ----------- -----------NULL NULL 1212 NULL NULL 2 12 NULL NULL 3 4 12 NULL NULL 4 4 122a b 122 a b 122 a b 122 c d 11111c d 1111 121212 c d 11111 121212 12121212 1221212c d 111 11111111 121212 12111111111111 1221212 e NULL 12 12 12 12 12 12 12 12 12 12 12 122 12 122 12 为了达到结果,你希望省略 两者 的PARTITION BY和ORDER BY,用空的OVER()条款(如上所示)。 |
|