我有三个表,其中一个映射另外两个,我的查询通过引用表(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,但大多数文章删除了重复项。
答案 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;