通过 sql 对分区计数不同

Count Distinct over partition by sql

我有一个table喜欢

col1ID  col2String Col3ID Col4String Col5Data
  1        xxx       20      abc     14-09-2018
  1        xxx       20      xyz     14-09-2018
  2        xxx       30      abc     14-09-2018
  2        xxx       30      abc     14-09-2018 

我想添加一列来计算我在 col4String 组中按 col1ID 和 col3ID 有多少个不同的字符串。

所以像

COUNT(DISTINCT (Col4String)) over (partition by col1ID, col3ID)

但是它不起作用,我收到一个错误

Use of DISTINCT is not allowed with the OVER clause.
Msg 102, Level 15, State 1, Line 23.

我有更多列,如 col2String、col5Data,但它们不应该受到影响,所以我不能在 SELECT 的开头使用 distinct,而且 dense_rank() 似乎也没有以我为例。

谢谢你的帮助。

试试这个方法;

select * from TableX X
outer apply(select count(*) as stringCount , X2.Col4String 
            from TableX X2 on X.col1ID= X2.col1ID and X.col3ID = X2.col3ID
            group by X2.Col4String ) K

显然 SQL 服务器中的 window 函数不支持 distinct,因此,您可以改用子查询。沿着这些线的东西:

 select (
           select COUNT(DISTINCT Col4String) 
           from your_table t2
           where t1.col1ID = t2.col1ID and t1.col3ID = t2.col3ID
        )
 from your_table t1

试试这个:

DECLARE @DataSource TABLE
(
    [col1ID] INT
   ,[col2String] VARCHAR(12) 
   ,[Col3ID]  INT
   ,[Col4String]  VARCHAR(12)
   ,[Col5Data] DATE
);

INSERT INTO @DataSource
VALUES (1, 'xxx', 20, 'abc', '2018-09-14')
      ,(1, 'xxx', 20, 'xyz', '2018-09-14')
      ,(2, 'xxx', 30, 'abc', '2018-09-14')
      ,(2, 'xxx', 30, 'abc', '2018-09-14');

SELECT *
     ,dense_rank() over (partition by col1ID, col3ID order by [Col4String])  + dense_rank() over (partition by col1ID, col3ID order by [Col4String] desc) - 1
FROM @DataSource

我会使用 APPLY :

SELECT t.*, t1.Col4String_Cnt
FROM table t CROSS APPLY
     (SELECT COUNT(DISTINCT t1.Col4String) AS Col4String_Cnt
      FROM table t1
      WHERE t1.col1ID = t.col1ID AND t1.col3ID  = t.col3ID 
     ) t1;

您可以使用额外级别的 window 功能来完成此操作。一种方法使用 dense_rank():

SELECT . . .,
       MAX(DR) OVER (PARTITION BY col1ID, col3ID)
FROM (SELECT t.*, 
             DENSE_RANK() OVER (PARTITION BY col1ID, col3ID ORDER BY Col4String) as dr
      FROM t
     ) t