2015-06-10 91 views
1

我面臨着我的查詢的邏輯問題。完全加入羣組

我有兩個表Table1Table2,其中Table1組成:

  • value要被總計
  • Id
  • Code被分組持有外國關鍵Table2

而且Table2

  • Code
  • Des的代碼

我試圖做的是文字說明,由Table1.Id組成,完全加入Table2.Code,但是,f或每個結果組,我希望顯示查詢生成的每個組的Table2中的所有行。

示例代碼:

SELECT 
    Table2.Code, Table1.Id, Table2.DES, 
    SUM(Table1.Value) AS SUM_VAL 
FROM 
(
    SELECT 'A' AS Code, 1 AS Id, 10 AS Value FROM DUAL UNION 
    SELECT 'A' AS Code, 2 AS Id, 20 AS Value FROM DUAL UNION 
    SELECT 'B' AS Code, 1 AS Id, 10 AS Value FROM DUAL UNION 
    SELECT 'B' AS Code, 1 AS Id, 30 AS Value FROM DUAL UNION 
    SELECT 'B' AS Code, 2 AS Id, 50 AS Value FROM DUAL UNION 
    SELECT 'C' AS Code, 1 AS Id, 40 AS Value FROM DUAL UNION 
    SELECT 'C' AS Code, 2 AS Id, 60 AS Value FROM DUAL UNION 
    SELECT 'D' AS Code, 1 AS Id, 20 AS Value FROM DUAL 

) Table1 
FULL JOIN 
(
    SELECT 'A' AS Code, 'This is A' AS DES FROM DUAL UNION 
    SELECT 'B' AS Code, 'This is B' AS DES FROM DUAL UNION 
    SELECT 'C' AS Code, 'This is C' AS DES FROM DUAL UNION 
    SELECT 'D' AS Code, 'This is D' AS DES FROM DUAL 
) Table2 
ON Table1.Code = Table2.Code 
GROUP BY 
    Table2.Code, Table1.Id, Table2.DES 
ORDER BY 
    Table2.Code, Table1.Id ASC 

結果:

A 1 This is A 10 
A 2 This is A 20 
B 1 This is B 40 
B 2 This is B 50 
C 1 This is C 40 
C 2 This is C 60 
D 1 This is D 20 

要求的結果:

A 1 This is A 10 
A 2 This is A 20 
B 1 This is B 40 
B 2 This is B 50 
C 1 This is C 40 
C 2 This is C 60 
D 1 This is D 20 
D 2 This is D 0 <- This is the target 
+0

coalesce(Table1.Code,Table2.Code)in select and group by? – jarlh

+0

這與這個問題有什麼關係? – simsim

+0

當table1中沒有命中時,改進了完整的外部聯接結果。 – jarlh

回答

1

你總得有顯示價值對(D,2)例如。通過與可能值的碼列表和平移NULL0

SELECT code.code, 
     code.id, 
     des.des, 
     NVL (SUM (val.value), 0) sum_val 
    FROM (SELECT 'A' code, 1 id FROM DUAL 
      UNION 
      SELECT 'A', 2 FROM DUAL 
      UNION 
      SELECT 'B', 1 FROM DUAL 
      UNION 
      SELECT 'B', 2 FROM DUAL 
      UNION 
      SELECT 'C', 1 FROM DUAL 
      UNION 
      SELECT 'C', 2 FROM DUAL 
      UNION 
      SELECT 'D', 1 FROM DUAL 
      UNION 
      SELECT 'D', 2 FROM DUAL) code 
     INNER JOIN (SELECT 'A' code, 'This is A' des FROM DUAL 
        UNION 
        SELECT 'B', 'This is B' FROM DUAL 
        UNION 
        SELECT 'C', 'This is C' FROM DUAL 
        UNION 
        SELECT 'D', 'This is D' FROM DUAL) des 
      ON code.code = des.code 
     LEFT OUTER JOIN (SELECT 'A' code, 1 id, 10 VALUE FROM DUAL 
          UNION ALL 
          SELECT 'A', 2, 20 FROM DUAL 
          UNION ALL 
          SELECT 'B', 1, 10 FROM DUAL 
          UNION ALL 
          SELECT 'B', 1, 30 FROM DUAL 
          UNION ALL 
          SELECT 'B', 2, 50 FROM DUAL 
          UNION ALL 
          SELECT 'C', 1, 40 FROM DUAL 
          UNION ALL 
          SELECT 'C', 2, 60 FROM DUAL 
          UNION ALL 
          SELECT 'D', 1, 20 FROM DUAL) val 
      ON code.code = val.code AND code.id = val.id 
GROUP BY code.code, code.id, des.des 
ORDER BY code, id 

UNION ALLval使用,因爲重複的可能發生。

不需要FULL OUTER JOIN

+0

雖然你的建議解決方案改變了查詢的整個結構,但是在我的原始代碼中這是不可能的,上面的代碼只是一個模仿我面對的情況和更復雜的code_的示例,但是你給了我提示要如何解決這個問題,謝謝。我會在幾分鐘內更新問題。 – simsim

+0

在完整的加入聲明(原始代碼)中: 我選擇了1和2,並將它們與** A **,** B **,** C **和** D **結合在一起給我所有** A **,** B **,** C **,** D **與** 1 **和** 2 **的可能性,以便'Table2'現在包含'Code','' Text'和'Id' ,然後在'Table1'和'Table2'之間的'join filter'上,我添加了'和Table1.id = table2.id',條件爲 這樣解決了問題 – simsim

+0

If只有代碼1和2永遠是相關的,這聽起來很合理。否則,你可以考慮Gordon Linoff倡導的動態方法。 –

1

如果你想ID和值的所有組合,然後使用cross join得到行和left join在其餘值帶來:

select t2.code, i.value, t2.desc, coalesce(cnt, 0) as cnt 
from (select distinct id from table1) i cross join 
    table2 t2 left join 
    (select id, value, count(*) as cnt 
     from table1 
     group by id, value 
    ) iv 
    on iv.id = i.id and iv.code = t2.code 

這應該是超過了所有上市更簡單手動組合。

+0

謝謝,我已經以類似的方式處理它,查看我對Jon Tofte-Hansen的評論回答 – simsim

+0

@simsim。 。 。這個解決方案的關鍵是通過「交叉連接」生成所有*行*,然後使用「左連接」添加適當的列。 –

1
SELECT 
    Table2.Code, Table2.NAT, Table2.DES, 
    SUM(Table1.Value) AS SUM_VAL 
FROM 
(
    SELECT 'A' AS Code, 'QA' AS Id, 10 AS Value FROM DUAL UNION 
    SELECT 'A' AS Code, 'NQA' AS Id, 20 AS Value FROM DUAL UNION 
    SELECT 'B' AS Code, 'QA' AS Id, 10 AS Value FROM DUAL UNION 
    SELECT 'B' AS Code, 'QA' AS Id, 30 AS Value FROM DUAL UNION 
    SELECT 'B' AS Code, 'NQA' AS Id, 50 AS Value FROM DUAL UNION 
    SELECT 'C' AS Code, 'QA' AS Id, 40 AS Value FROM DUAL UNION 
    SELECT 'C' AS Code, 'NQA' AS Id, 60 AS Value FROM DUAL UNION 
    SELECT 'D' AS Code, 'QA' AS Id, 20 AS Value FROM DUAL 

) Table1 
FULL JOIN 
(
    SELECT 'QA' NAT,'A' AS Code, 'This is A' AS DES FROM DUAL UNION 
    SELECT 'QA' NAT,'B' AS Code, 'This is B' AS DES FROM DUAL UNION 
    SELECT 'QA' NAT,'C' AS Code, 'This is C' AS DES FROM DUAL UNION 
    SELECT 'QA' NAT,'D' AS Code, 'This is D' AS DES FROM DUAL 
    UNION 
    SELECT 'NQA' NAT,'A' AS Code, 'This is A' AS DES FROM DUAL UNION 
    SELECT 'NQA' NAT,'B' AS Code, 'This is B' AS DES FROM DUAL UNION 
    SELECT 'NQA' NAT,'C' AS Code, 'This is C' AS DES FROM DUAL UNION 
    SELECT 'NQA' NAT,'D' AS Code, 'This is D' AS DES FROM DUAL 
) Table2 
on TABLE2.NAT = TABLE1.ID 
     AND Table2.Code= Table1.Code 
GROUP BY 
    Table2.Code, Table2.NAT, Table2.DES 
ORDER BY 
    Table2.Code, Table2.NAT ASC