I'm trying to write the following in order to get a running total of distinct NumUsers, like so:
NumUsers = COUNT(DISTINCT [UserAccountKey]) OVER (PARTITION BY [Mth])
Management studio doesn't seem too happy about this. The error disappears when I remove the DISTINCT
keyword, but then it won't be a distinct count.
DISTINCT
does not appear to be possible within the partition functions. How do I go about finding the distinct count? Do I use a more traditional method such as a correlated subquery?
Looking into this a bit further, maybe these OVER
functions work differently to Oracle in the way that they cannot be used in SQL-Server
to calculate running totals.
I've added a live example here on SQLfiddle where I attempt to use a partition function to calculate a running total.
Count Distinct is not supported by window partitioning, we need to find a different way to achieve the same result.
Yes, you can use COUNT() and DISTINCT together to display the count of only distinct rows. SELECT COUNT(DISTINCT yourColumnName) AS anyVariableName FROM yourTableName; To understand the above syntax, let us create a table.
now you can use the expression Sum(Keycounter) instead of Count(Distinct %Keytobecounted).
The COUNT DISTINCT function returns the number of unique values in the column or expression, as the following example shows. SELECT COUNT (DISTINCT item_num) FROM items; If the COUNT DISTINCT function encounters NULL values, it ignores them unless every value in the specified column is NULL.
There is a very simple solution using dense_rank()
dense_rank() over (partition by [Mth] order by [UserAccountKey]) + dense_rank() over (partition by [Mth] order by [UserAccountKey] desc) - 1
This will give you exactly what you were asking for: The number of distinct UserAccountKeys within each month.
Necromancing:
It's relativiely simple to emulate a COUNT DISTINCT over PARTITION BY with MAX via DENSE_RANK:
;WITH baseTable AS ( SELECT 'RM1' AS RM, 'ADR1' AS ADR UNION ALL SELECT 'RM1' AS RM, 'ADR1' AS ADR UNION ALL SELECT 'RM2' AS RM, 'ADR1' AS ADR UNION ALL SELECT 'RM2' AS RM, 'ADR2' AS ADR UNION ALL SELECT 'RM2' AS RM, 'ADR2' AS ADR UNION ALL SELECT 'RM2' AS RM, 'ADR3' AS ADR UNION ALL SELECT 'RM3' AS RM, 'ADR1' AS ADR UNION ALL SELECT 'RM2' AS RM, 'ADR1' AS ADR UNION ALL SELECT 'RM3' AS RM, 'ADR1' AS ADR UNION ALL SELECT 'RM3' AS RM, 'ADR2' AS ADR ) ,CTE AS ( SELECT RM, ADR, DENSE_RANK() OVER(PARTITION BY RM ORDER BY ADR) AS dr FROM baseTable ) SELECT RM ,ADR ,COUNT(CTE.ADR) OVER (PARTITION BY CTE.RM ORDER BY ADR) AS cnt1 ,COUNT(CTE.ADR) OVER (PARTITION BY CTE.RM) AS cnt2 -- Not supported --,COUNT(DISTINCT CTE.ADR) OVER (PARTITION BY CTE.RM ORDER BY CTE.ADR) AS cntDist ,MAX(CTE.dr) OVER (PARTITION BY CTE.RM ORDER BY CTE.RM) AS cntDistEmu FROM CTE
Note:
This assumes the fields in question are NON-nullable fields.
If there is one or more NULL-entries in the fields, you need to subtract 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With