【问题标题】:Count Distinct over partition by sql通过sql对分区计数不同
【发布时间】:2019-04-30 06:24:54
【问题描述】:

我有一张这样的桌子

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 

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

类似

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

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

OVER 子句不允许使用 DISTINCT。
消息 102,第 15 级,状态 1,第 23 行。

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

感谢您的帮助。

【问题讨论】:

  • DISTINCT 不是函数,即不需要括号。只需执行COUNT(DISTINCT Col4String) over ... 即可使代码更清晰。
  • 没有括号也不行
  • 抱歉,我没有尝试回答这个问题,这只是一个一般性建议。

标签: sql sql-server tsql count distinct


【解决方案1】:

试试这个:

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

【讨论】:

  • 看来我使用 dense_rank() 的方式有误 - 也有效!
【解决方案2】:

显然 SQL Server 中的窗口函数不支持 distinct,因此,您可以改用子查询。大致如下:

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

【讨论】:

  • 这行得通,但我的问题是 my_table t1 是一个很大的子查询,所以复制相同的代码看起来不太好-编辑-我可以使用 CTE
【解决方案3】:

试试这个方法;

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

【讨论】:

    【解决方案4】:

    我会使用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;
    

    【讨论】:

      【解决方案5】:

      您可以使用额外级别的窗口函数来做到这一点。一种方法使用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 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-24
        • 2021-01-27
        • 1970-01-01
        • 2012-06-16
        • 2010-10-29
        • 2015-06-04
        相关资源
        最近更新 更多