计算唯一列但返回重复项

时间:2018-03-07 17:43:21

标签: sql-server

我有三个表,其中一个映射另外两个,我的查询通过引用表(C)返回表(A)的列表,其中包含多个表(B)。

我的查询

SELECT a.A_ID, a.DESC, b.B_ID, b.NAME, COUNT(*) OVER() AS TOTAL
FROM table_A a
LEFT JOIN table_C c ON c.A_ID = a.A_ID
LEFT JOIN table_B b on b.B_ID = c.B_ID

table_A:

A_ID   |   DESC
10001  |   Sample
10002  |   Sample
10003  |   Sample

表-B:

B_ID   |   NAME
10001  |   Name 1
10002  |   Name 2

table_C:

C_ID   |   A_ID   |   B_ID
10001  |  10001   |  10001
10002  |  10001   |  10002
10003  |  10002   |  10001

查询返回我想要的数据,但我的总计也会计算重复数据。

  |  A_ID  |  A_DESC  |  B_ID  |  B_NAME  | TOTAL  
1 | 10001  |  Sample  | 10001  |  Name_1  |   4
2 | 10001  |  Sample  | 10002  |  Name_2  |   4
3 | 10002  |  Sample  | 10001  |  Name_1  |   4
4 | 10003  |  Sample  | NULL   |  NULL    |   4

它重复计算重复,我理解数量很好..计数。我遇到了麻烦,因为我的方案需要上面的所有数据,但需要正确的计数(不计算重复数据但返回重复数据)

这是我想要的回报

  |  A_ID  |  A_DESC  |  B_ID  |  B_NAME  | TOTAL  
1 | 10001  |  Sample  | 10001  |  Name_1  |   3
2 | 10001  |  Sample  | 10002  |  Name_2  |   3
3 | 10002  |  Sample  | 10001  |  Name_1  |   3
4 | 10003  |  Sample  | NULL   |  NULL    |   3

我还是sql的新手,我用网站搜索了这个:stackoverflow.com,但大多数文章删除了重复项。

1 个答案:

答案 0 :(得分:3)

您可以使用两个COUNT(DISTINCT Col) OVER()函数执行相当于DENSE_RANK()的操作:

DECLARE @A TABLE (A_ID INT, [Desc] VARCHAR(255));
DECLARE @B TABLE (B_ID INT, Name VARCHAR(255));
DECLARE @C TABLE (C_ID INT, A_ID INT, B_ID INT);
INSERT @A VALUES (10001, 'Sample'), (10002, 'Sample'), (10003, 'Sample');
INSERT @B VALUES (10001, 'Name 1'), (10002, 'Name 2');
INSERT @C VALUES (10001, 10001, 10001), (10002, 10001, 10002), (10003, 10002, 10001);


SELECT a.A_ID, a.[DESC], b.B_ID, b.NAME, COUNT(*) OVER() AS TOTAL,
        DenseRankAsc = DENSE_RANK() OVER(ORDER BY a.A_ID ASC),
        DenseRankDesc = DENSE_RANK() OVER(ORDER BY a.A_ID DESC),
        CountDistinct = DENSE_RANK() OVER(ORDER BY a.A_ID ASC) 
                        + DENSE_RANK() OVER(ORDER BY a.A_ID DESC) - 1
FROM @A a
LEFT JOIN @C c ON c.A_ID = a.A_ID
LEFT JOIN @B b on b.B_ID = c.B_ID;

这给出了

A_ID    DESC    B_ID    NAME        TOTAL   DenseRankAsc    DenseRankDesc   CountDistinct
-------------------------------------------------------------------------------------------
10003   Sample  NULL    NULL        4           3                   1           3
10002   Sample  10001   Name 1      4           2                   2           3
10001   Sample  10001   Name 1      4           1                   3           3
10001   Sample  10002   Name 2      4           1                   3           3

前提是通过对升序和降序进行排序,您可以识别唯一项目的总数。

话虽这么说,一个更简单的解决方案可能是在您知道结果已经不同的时候进行计数,例如:

DECLARE @A TABLE (A_ID INT, [Desc] VARCHAR(255));
DECLARE @B TABLE (B_ID INT, Name VARCHAR(255));
DECLARE @C TABLE (C_ID INT, A_ID INT, B_ID INT);
INSERT @A VALUES (10001, 'Sample'), (10002, 'Sample'), (10003, 'Sample');
INSERT @B VALUES (10001, 'Name 1'), (10002, 'Name 2');
INSERT @C VALUES (10001, 10001, 10001), (10002, 10001, 10002), (10003, 10002, 10001);


SELECT a.A_ID, a.[DESC], b.B_ID, b.NAME, a.TOTAL
FROM (SELECT *, COUNT(*) OVER() AS Total FROM @A) a 
LEFT JOIN @C c ON c.A_ID = a.A_ID
LEFT JOIN @B b on b.B_ID = c.B_ID;