以下是两个表TBL1和TBL2
TBL1
ID1 Item Val1
100 Shirt 10
101 Shirt 15
102 Shirt 10
100 Shirt 10
100 Shirt 10
103 Pants 14
TBL2
ID2 ID1 Val2
901 100 24
902 101 15
903 102 31
904 100 45
905 100 62
906 103 17
现在我在这两个表上执行以下查询:
SELECT TBL1.Item AS Item,
Count(DISTINCT TBL1.ID1) AS Cpt,
SUM (TBL1.Val1) AS Tot1,
SUM (TBL2.Val2) AS Tot2
FROM TBL1, TBL2
WHERE TBL1.ID1 = TBL2.ID2
GROUP BY TBL1.Item
这里的问题是SUM(TBL1.Val1)
不会考虑冗余值,即相同的TBL1.ID1。如果我使用SUM(DISTINCT TBL1.ID1)
,
一些信息不会被考虑在内。对于ID1 = 102,Val1 = 10将不会在SUM (DISTINCT TBL1.ID1)
中使用。
您如何认为我可以重写该查询,以便SUM仅针对不同的ID1运行?结果如下:
Item Cpt Tot1 Tot2
Shirt 5 35 177
Pants 1 14 17
答案 0 :(得分:3)
这就是我的意思:
DECLARE @TBL1 TABLE (
ID1 INT
, Item VARCHAR(10)
, Val1 INT
);
DECLARE @TBL2 TABLE (
ID2 INT
, ID1 INT
, Val2 INT
);
INSERT INTO @TBL1 (ID1, Item, Val1)
VALUES (100, 'Shirt', 10)
, (101, 'Shirt', 15)
, (102, 'Shirt', 10)
, (100, 'Shirt', 10)
, (100, 'Shirt', 10)
, (103, 'Pants', 14);
INSERT INTO @TBL2 (ID2, ID1, Val2)
VALUES (901, 100, 24)
, (902, 101, 15)
, (903, 102, 31)
, (904, 100, 45)
, (905, 100, 62)
, (906, 103, 17);
;WITH Items (ID1, Item, Val1)
AS (
SELECT DISTINCT ID1, Item, Val1
FROM @TBL1
)
, Items2 (Item, Tot1)
AS (
SELECT Item, SUM(Val1)
FROM Items
GROUP BY Item
)
, TBL2 (ID1, Tot2)
AS (
SELECT ID1, SUM(Val2)
FROM @TBL2
GROUP BY ID1
)
SELECT T.Item
, COUNT(T1.ID1) AS Cpt
, T.Tot1
, SUM(DISTINCT T2.Tot2)
FROM Items2 AS T
INNER JOIN @TBL1 AS T1
ON T1.Item = T.Item
INNER JOIN TBL2 AS T2
ON T2.ID1 = T1.ID1
GROUP BY T.Item, T.Tot1;
它不是那么优雅,但它完成了工作。结果如下:
╔═══════╦═════╦══════╦══════╗
║ Item ║ Cpt ║ Tot1 ║ Tot2 ║
╠═══════╬═════╬══════╬══════╣
║ Pants ║ 1 ║ 14 ║ 17 ║
║ Shirt ║ 5 ║ 35 ║ 177 ║
╚═══════╩═════╩══════╩══════╝
上运行查询
SELECT T.Item
, COUNT(T1.ID1) AS Cpt
, T.Tot1
, SUM(DISTINCT T2.Tot2) AS Tot2
FROM (
SELECT Item, SUM(Val1) AS Tot1
FROM (SELECT DISTINCT ID1, Item, Val1 FROM @TBL1) AS X
GROUP BY X.Item
) AS T
INNER JOIN @TBL1 AS T1
ON T1.Item = T.Item
INNER JOIN (
SELECT ID1, SUM(Val2) AS Tot2
FROM @TBL2
GROUP BY ID1
) AS T2
ON T2.ID1 = T1.ID1
GROUP BY T.Item, T.Tot1;
这也可以在data.stackexchange.com上运行
如果在运行SUM(DISTINCT T2.Tot2) AS Tot2
时会出现一些欺骗,以前的查询可能会理论上提供错误的结果。这应该可以正常工作,虽然它需要额外的连接。
SELECT T1.Item
, T3.Cpt
, T1.Tot1
, T2.Tot2
FROM (
SELECT Item, SUM(Val1) AS Tot1
FROM (SELECT DISTINCT ID1, Item, Val1 FROM @TBL1) AS X
GROUP BY X.Item
) AS T1
INNER JOIN (
SELECT T1.Item, SUM(Val2) AS Tot2
FROM (SELECT DISTINCT ID1, Item, Val1 FROM @TBL1) AS T1
INNER JOIN @TBL2 AS T2
ON T2.ID1 = T1.ID1
GROUP BY T1.Item
) AS T2
ON T2.Item = T1.Item
INNER JOIN (
SELECT Item, COUNT(*) AS Cpt
FROM @TBL1
GROUP BY Item
) AS T3
ON T3.Item = T1.Item;