通过sql计算分区上的不同计数

通过sql计算分区上的不同计数,sql,sql-server,tsql,count,distinct,Sql,Sql Server,Tsql,Count,Distinct,我有一张像这样的桌子 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  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,而
densite\u 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 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
试试这个:

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

我会使用
应用

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;

您可以使用额外级别的窗口函数来实现这一点。一种方法使用
稠密的\u rank()


DISTINCT
不是函数,即不需要括号。只需对…<代码>进行计数(不同的Col4String)即可使代码更清晰。没有括号也不起作用。对不起,我没有尝试回答这个问题,这只是一个一般性的建议。这可能是重复的,但我的问题是,我的表t1是一个大的子查询,所以复制相同的代码看起来不太好-编辑-我可以使用CTEIt,看起来我用了一种错误的方式使用了
densite\u 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