0

我有 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

我需要做的是从两个表的 ACCTS 字段中提取按 SL 排序的汇总。

这是我目前使用的 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

任何帮助将非常感激。

4

3 回答 3

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 上将所有这些聚合查询连接在一起以获取结果集。因为您在某些聚合中缺少条目,所以您需要LEFTinLEFT JOINCOALESCE()items。

SQL小提琴

这是全部查询

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

结果就是你要找的

|  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

于 2014-10-31T19:49:52.720 回答
0

我不认为子查询会胜过 count distinct,我也应该避免在同一个表上进行多个连接

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

SQL小提琴

结果相同,但表扫描更少

于 2014-10-31T20:16:20.080 回答
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
于 2014-10-31T20:52:21.673 回答