使用左外连接选择查询,使用group by选择和

时间:2014-07-29 07:02:32

标签: mysql sql oracle left-join

我有3个表格,例如

父表:TEST_SUMMARY

子表:TEST_DETAIL,TEST_DETAIL2

Image Attached

我在图像中显示数据,并希望输出结果显示在图像中,

我尝试了以下2个查询,但没有给出预期的输出

SELECT s.NAME, sum(s.AMT), sum(d.d_amt), sum(d2.d2_amt)
FROM TEST_SUMMARY s LEFT OUTER JOIN TEST_DETAIL d
ON s.ID = d.SUMMARY_ID 
LEFT OUTER JOIN TEST_DETAIL2 d2
ON s.ID =d2.SUMMARY_ID
GROUP BY s.NAME
ORDER BY s.NAME;

select rs1.*,rs2.total1,rs3.total2
FROM
(select id, name,amt from TEST_SUMMARY a) RS1,
(select SUMMARY_ID, sum(d_amt) over(partition by summary_id ) total1 from TEST_DETAIL a) RS2,
(select SUMMARY_ID, sum(d2_amt) over(partition by summary_id ) total2 from TEST_DETAIL2 a) RS3
where rs1.id(+)= RS2.SUMMARY_ID
and rs1.id(+)= RS3.SUMMARY_ID;

创建表并插入数据测试查询

CREATE TABLE TEST_SUMMARY(ID NUMBER, NAME VARCHAR2(20 BYTE),AMT  NUMBER(10,2));

CREATE TABLE TEST_DETAIL (ID NUMBER, SUMMARY_ID NUMBER, NAME VARCHAR(20), D_AMT NUMBER(10,2));

CREATE TABLE TEST_DETAIL2 (ID NUMBER, SUMMARY_ID NUMBER, NAME VARCHAR(20), D2_AMT NUMBER(10,2));

INSERT INTO TEST_SUMMARY VALUES (1, 'NAME1', 100);
INSERT INTO TEST_SUMMARY VALUES (4, 'NAME1', 150);
INSERT INTO TEST_SUMMARY VALUES (6, 'NAME1', 50);
INSERT INTO TEST_SUMMARY VALUES (2, 'NAME2', 200);
INSERT INTO TEST_SUMMARY VALUES (3, 'NAME3', 300);

INSERT INTO TEST_DETAIL VALUES (1, 1, 'NAME11', 11);
INSERT INTO TEST_DETAIL VALUES (2, 1, 'NAME12', 12);

INSERT INTO TEST_DETAIL2 VALUES (1, 1, 'NAME_2_11', 1);
INSERT INTO TEST_DETAIL2 VALUES (2, 1, 'NAME_2_12', 1);

3 个答案:

答案 0 :(得分:3)

为MySQL和Oracle解决问题的一种方法是使用子查询通过按名称汇总详细信息表中的总和来帮助解决重复问题,这样您就可以使用普通连接进行汇总;

SELECT ts.name, SUM(ts.amt) amt1, MAX(td1.amt) amt2, MAX(td2.amt) amt3
FROM TEST_SUMMARY ts
LEFT JOIN (
  SELECT ts.name, SUM(td.d_amt) amt 
  FROM TEST_DETAIL td JOIN TEST_SUMMARY ts ON td.summary_id = ts.id
  GROUP BY ts.name) td1 ON ts.name = td1.name
LEFT JOIN (
  SELECT ts.name, SUM(td.d2_amt) amt 
  FROM TEST_DETAIL2 td JOIN TEST_SUMMARY ts ON td.summary_id = ts.id
  GROUP BY ts.name) td2 ON ts.name = td2.name
GROUP BY ts.name
ORDER BY ts.name

A MySQL SQLfiddlean Oracle SQLfiddle来测试。

答案 1 :(得分:1)

你可以试试这个:

SELECT
    TEST_SUMMARY.NAME,
    TEST_SUMMARY.AMT AS AMT1,
    (
        SELECT
            SUM(TEST_DETAIL.D_AMT)
        FROM
            TEST_DETAIL
        WHERE
            TEST_DETAIL.SUMMARY_ID=TEST_SUMMARY.ID
    ) AS AMT2,
    (
        SELECT
            SUM(TEST_DETAIL2.D2_AMT)
        FROM
            TEST_DETAIL2
        WHERE
            TEST_DETAIL2.SUMMARY_ID=TEST_SUMMARY.ID
    ) AS AMT3
FROM
    TEST_SUMMARY

<强>更新

如果您有许多相同的名称,您基本上可以这样做。但问题是你应该对其他领域(AMT1,AMT2)做些什么?你应该将它们相加到同一个名称,或者最大值是否足够。取决于您的要求:

SELECT
    TEST_SUMMARY.NAME,
    SUM(TEST_SUMMARY.AMT) AS AMT,
    SUM(tblAMT2.AMT2) AS AMT2,
    SUM(tblAMT3.AMT3) AS AMT3
FROM
    TEST_SUMMARY
    LEFT JOIN
    (
        SELECT
            SUM(TEST_DETAIL.D_AMT) AS AMT2,
            TEST_DETAIL.SUMMARY_ID
        FROM
            TEST_DETAIL
        GROUP BY
            TEST_DETAIL.SUMMARY_ID
    ) AS tblAMT2
        ON TEST_SUMMARY.ID=tblAMT2.SUMMARY_ID
    LEFT JOIN
    (
        SELECT
            SUM(TEST_DETAIL2.D2_AMT) AS AMT3,
            TEST_DETAIL2.SUMMARY_ID
        FROM
            TEST_DETAIL2
        GROUP BY
            TEST_DETAIL2.SUMMARY_ID
    ) AS tblAMT3
        ON TEST_SUMMARY.ID=tblAMT3.SUMMARY_ID
GROUP BY
    TEST_SUMMARY.NAME

答案 2 :(得分:0)

试试这个:

  SELECT TS.NAME, TS.AMT AS AMT1, SUM(TD.D_AMT) AS AMT2, SUM(TD2.D2_AMT) AS AMT3
    FROM TEST_SUMMARY TS LEFT OUTER JOIN TEST_DETAIL TD   ON TS.ID = TD.SUMMARY_ID
                         LEFT OUTER JOIN TEST_DETAIL2 TD2 ON TS.ID = TD2.SUMMARY_ID
GROUP BY TS.NAME, TS.AMT
ORDER BY TS.NAME, TS.AMT