Skip to content Skip to sidebar Skip to footer

Tsql Over Clause: Count(*) Over (order By A)

This is my code: 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 V

Solution 1:

It gives a running total (this functionality was not implemented in SQL Server until version 2012.)

The ORDER BY defines the window to be aggregated with UNBOUNDED PRECEDING and CURRENT ROW as the default when not specified. SQL Server defaults to the less well performingRANGE option rather than ROWS.

They have different semantics in the case of ties in that the window for the RANGE version includes not just the current row (and preceding rows) but also any additional tied rows with the same value of a as the current row. This can be seen in the number of rows counted by each in the results below.

SELECT  a, 
        b,
        COUNT(*) OVER (ORDERBY a 
                         ROWSBETWEEN UNBOUNDED PRECEDING ANDCURRENTROW) AS  [Rows],
        COUNT(*) OVER (ORDERBY a 
                         RANGEBETWEEN UNBOUNDED PRECEDING ANDCURRENTROW) AS [Range],
        COUNT(*) OVER() AS [Over()]
    FROM    t;

Returns

a        b        Rows        Range       Over()-------------------------------------------------NULLNULL1412NULLNULL2412NULLNULL3412NULLNULL4412
a        b        5712
a        b        6712
a        b        7712c        d        81112c        d        91112c        d        101112c        d        111112
e        NULL121212

To achieve the result that you were expecting to get omit both the PARTITION BY and ORDER BY and use an empty OVER() clause (also shown above).

Solution 2:

If ROWS/RANGE is not specified but ORDER BY is specified, RANGE UNBOUNDED PRECEDING AND CURRENT ROW is used as the default for window frame So what does that mean, let's focus on "UNBOUNDED PRECEDING AND CURRENT ROW". This gives a running total from the starting row to the current row. But in case if you want to have an overall count then you can also specify

"UNBOUNDED PRECEDING AND UNBOUNDED Following" This considers entire data set and Over() is just a shortcut of this

select a,b,
count(*) over(orderby a) as [count],
COUNT(*) OVER (ORDERBY a 
                         RANGEBETWEEN UNBOUNDED PRECEDING ANDCURRENTROW) AS [Range],
COUNT(*) OVER (ORDERBY a 
                         ROWSBETWEEN UNBOUNDED PRECEDING ANDCURRENTROW) AS  [Rows],
COUNT(*) OVER (ORDERBY a 
                         RANGEBETWEEN UNBOUNDED PRECEDING AND UNBOUNDED Following) AS [Range_Unbounded_following],
COUNT(*) OVER (ORDERBY a 
                         ROWsBETWEEN UNBOUNDED PRECEDING AND UNBOUNDED Following) AS [Row_Unbounded_following]
,COUNT(*) OVER () AS [Plain_over]
from t 
orderby [count]

Result is

a        b        count       Range       Rows        Range_Unbounded_following Row_Unbounded_following Plain_over
------------------------------------------------------------------------------------------------------------NULLNULL441121212NULLNULL442121212NULLNULL443121212NULLNULL444121212
a        b        775121212
a        b        776121212
a        b        777121212c        d        11118121212c        d        11119121212c        d        111110121212c        d        111111121212
e        NULL121212121212

Post a Comment for "Tsql Over Clause: Count(*) Over (order By A)"