Join

連接多個表時返回的 SQL 擠壓行

  • October 2, 2018

我有一個數據庫,其中有一個主要項目的表,讓我們用主鍵“id”將它稱為 A。然後有許多表(B,C …),每個表對應於每個項目可以具有0個或多個的某些屬性。屬性表中的每一行都有一個外鍵(‘item_id’),指定它對應的主要項目,它們還有一個用於辨識目的的主鍵’id’。

我正在嘗試進行查詢,該查詢將從選擇的屬性表中獲取所有具有所有屬性的項目。例如,如果我想要有關所有屬性 B 和 C 的資訊,我嘗試了類似

SELECT A.id, B.id, C.id 
FROM A
LEFT JOIN B ON A.id=B.item_id
LEFT JOIN C ON A.id=C.item_id

但是,對於在 B 中具有 2 個屬性,在 C 中具有 3 個屬性的項目,這將為該項目返回 6 行:

----------------------------
| A.id  |  B.id  |  C.id   |
----------------------------
|    1  |     1  |     1   |
|    1  |     1  |     2   |
|    1  |     1  |     3   |
|    1  |     2  |     1   |
|    1  |     2  |     2   |
|    1  |     2  |     3   |
|    2  |  NULL  |     1   |
.                          
. 
.

雖然在最好的世界中,該項目只需要 3 行:

----------------------------
| A.id  |  B.id  |  C.id   |
----------------------------
|    1  |     1  |     1   |
|    1  |     2  |     2   |
|    1  |  NULL? |     3   |
|    2  |  NULL  |     1   |
.                          
. 
.

無論如何以這種方式“壓縮”行,以便為每個項目返回的行數是該項目相關表中屬性數的最大值(或者至少一行具有 NULL 屬性,如果它沒有’沒有)?每個項目的返回行數可以隨著請求的屬性數呈指數增長……

或者是收集屬性資訊以對每個屬性表進行一次查詢的最佳方法,每個查詢中只有一個 JOIN?

就像是

WITH BN AS (SELECT id, 
                  item_id, 
                  ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY id) rn 
           FROM B),
    CN AS (SELECT id, 
                  item_id, 
                  ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY id) rn 
           FROM C)
SELECT A.id, BC.id1, BC.id2
FROM A
LEFT JOIN (SELECT BN.item_id item_id, BN.id id1, CN.id id2
          FROM BN 
          FULL OUTER JOIN CN ON BN.item_id = CN.item_id
                            AND BN.rn = CN.rn ) BC ON A.id = BC.item_id

引用自:https://dba.stackexchange.com/questions/219051