我有3个表,我需要从中选择和汇总数据。
Table: IDEA
REFERENCE SL
128 SL1
200 SL1
201 SL2
205 SL3
Table: ACCT1
IDEA_REF ACCTS
128 5
128 2
200 3
205 4
Table: ACCT2
IDEA_REF ACCTS
201 3
205 4
205 3
我需要做的是从SL排序摘要,并使用两个表的ACCTS字段中的总计。
这是我到目前为止使用的SQL:
SELECT I.SL AS SL, COUNT(DISTINCT I.REFERENCE) AS NO,
SUM(CASE WHEN A1.IDEA_REF=I.REFERENCE THEN A1.ACCTS ELSE 0 END) AS ACCT1,
SUM(CASE WHEN A2.IDEA_REF=I.REFERENCE THEN A2.ACCTS ELSE 0 END) AS ACCT2
FROM IDEA I
LEFT JOIN ACCT1 A1 ON A1.IDEA_REF=I.REFERENCE
LEFT JOIN ACCT2 A2 ON A2.IDEA_REF=I.REFERENCE
WHERE A2.IDEA_REF IN I.REFERENCE OR A1.IDEA_REF IN I.REFERENCE
GROUP BY I.SL
我发现的问题是ACCT1和ACCT2表中有多个值并且引用了IDEA表。以下是此查询的结果:
SL NO ACCT1 ACCT2
SL1 2 10 0
SL2 1 0 3
SL3 1 8 7
SL3行将ACCT1和ACCT2值加两次。我似乎无法找到适当的方法来添加适当的次数。
所需的输出是:
SL NO ACCT1 ACCT2
SL1 2 10 0
SL2 1 0 3
SL3 1 4 7
非常感谢任何帮助。
答案 0 :(得分:0)
您要求三个单独的聚合,但是您尝试在一个查询中计算它们。
要获得NO
(不同项目的数量),您可以
SELECT SL,
COUNT(*) AS NO
FROM IDEA
GROUP BY SL
要获得ACCT1
项,您可以这样做:
SELECT SL,
SUM(ACCTS) AS ACCT1
FROM IDEA
JOIN ACCT1 ON IDEA.REFERENCE = ACCT1.IDEA_REF
GROUP BY SL
以同样的方式,您可以获得ACCT2
SELECT SL,
SUM(ACCTS) AS ACCT2
FROM IDEA
JOIN ACCT2 ON IDEA.REFERENCE = ACCT2.IDEA_REF
GROUP BY SL
然后,您需要在SL上将所有这些聚合查询连接在一起以获取结果集。由于您在某些聚合中缺少条目,因此您需要LEFT
中的LEFT JOIN
和COALESCE()
项。
这是全部查询
SELECT Q.SL, NO,
COALESCE(ACCT1,0) AS ACCT1,
COALESCE(ACCT2,0) AS ACCT2
FROM (
SELECT SL,
COUNT(*) AS NO
FROM IDEA
GROUP BY SL
) Q
LEFT JOIN (
SELECT SL,
SUM(ACCTS) AS ACCT1
FROM IDEA
JOIN ACCT1 ON IDEA.REFERENCE = ACCT1.IDEA_REF
GROUP BY SL
) R ON Q.SL = R.SL
LEFT JOIN (
SELECT SL,
SUM(ACCTS) AS ACCT2
FROM IDEA
JOIN ACCT2 ON IDEA.REFERENCE = ACCT2.IDEA_REF
GROUP BY SL
) S ON Q.SL = S.SL
The result is what you are looking for:
| SL | NO | ACCT1 | ACCT2 |
|-----|----|-------|-------|
| SL1 | 2 | 10 | 0 |
| SL2 | 1 | 0 | 3 |
| SL3 | 1 | 4 | 7 |
看看这是如何工作的?你必须分别做每个聚合。
如果您使用的DBMS不知道JOIN ... USING()
语法,请改为使用ON Q.SL = R.SL
或相应的ON
子句。请参阅编辑,并查看此小提琴:http://sqlfiddle.com/#!2/63aa1/3/0
答案 1 :(得分:0)
我认为子查询的性能不会超过count,我也应避免在同一个表上多次连接
SELECT
i.SL,
COUNT(DISTINCT i.SL) NO,
COALESCE(SUM(a.sum1), 0) act1,
COALESCE(SUM(b.sum2), 0) act2
FROM
IDEA i
LEFT JOIN
(
SELECT
IDEA_REF,
SUM(ACCTS) sum1
FROM
ACCT1
GROUP BY IDEA_REF
) a
ON i.REFERENCE = a.IDEA_REF
LEFT JOIN
(
SELECT
IDEA_REF,
SUM(ACCTS) sum2
FROM
ACCT2
GROUP BY IDEA_REF
) b
ON i.REFERENCE = b.IDEA_REF
GROUP BY i.SL
结果相同但表扫描次数较少
答案 2 :(得分:0)
您可以使用UNION ALL
来实现结果SELECT
COMB.SL AS SL,
COUNT(DISTINCT COMB.REFERENCE) AS NO,
sum(T1) as ACCT1,
sum(T2) ACCT2
FROM (
SELECT
I.*,A1.ACCTS as t1,0 as t2
FROM
IDEA I
LEFT JOIN
ACCT1 A1 ON A1.IDEA_REF=I.REFERENCE
UNION ALL
SELECT
I.*,0 as t1,A2.ACCTS as t2
FROM
IDEA I
LEFT JOIN
ACCT2 A2 ON A2.IDEA_REF=I.REFERENCE
) as COMB
GROUP BY
COMB.SL