2009-01-14 72 views
2

我加入了三個表(執行完整的外部聯接),以便可以從所有表中檢索所有記錄。我面臨的問題是我加入表格的順序。加入3個表並檢索所有表中的所有記錄

表信息

alt text http://img235.imageshack.us/img235/7980/tableinfoow1.png

(1)如果我加入TABLE1,TABLE2,表3序列表,我得到兩行紀錄,B隊和1級

SELECT DISTINCT 
    (CASE WHEN T0.[TEAM] IS NOT NULL THEN T0.[TEAM] WHEN T1.[TEAM] IS NOT NULL THEN T1.[TEAM] WHEN T2.[TEAM] IS NOT NULL THEN T2.[TEAM] ELSE T0.[TEAM] END) AS [TEAM], 
    (CASE WHEN T0.[LEVEL] IS NOT NULL THEN T0.[LEVEL] WHEN T1.[LEVEL] IS NOT NULL THEN T1.[LEVEL] WHEN T2.[LEVEL] IS NOT NULL THEN T2.[LEVEL] ELSE T0.[LEVEL] END) AS [LEVEL], 
    T0.[VALUE1] AS [VALUE1], 
    T1.[VALUE2] AS [VALUE2], 
    T2.[VALUE3] AS [VALUE3] 

FROM TABLE1 T0 
FULL JOIN TABLE2 T1 ON T0.[TEAM] = T1.[TEAM] AND T0.[LEVEL] = T1.[LEVEL] 
FULL JOIN TABLE3 T2 ON T0.[TEAM] = T2.[TEAM] AND T0.[LEVEL] = T2.[LEVEL] 

( 2)如果我連接TABLE2,TABLE3,TABLE1序列中的表,我會得到正確的輸出行數。我對着

SELECT DISTINCT 
    (CASE WHEN T0.[TEAM] IS NOT NULL THEN T0.[TEAM] WHEN T1.[TEAM] IS NOT NULL THEN T1.[TEAM] WHEN T2.[TEAM] IS NOT NULL THEN T2.[TEAM] ELSE T0.[TEAM] END) AS [TEAM], 
    (CASE WHEN T0.[LEVEL] IS NOT NULL THEN T0.[LEVEL] WHEN T1.[LEVEL] IS NOT NULL THEN T1.[LEVEL] WHEN T2.[LEVEL] IS NOT NULL THEN T2.[LEVEL] ELSE T0.[LEVEL] END) AS [LEVEL], 
    T0.[VALUE1] AS [VALUE1], 
    T1.[VALUE2] AS [VALUE2], 
    T2.[VALUE3] AS [VALUE3] 

FROM TABLE2 T0 
FULL JOIN TABLE3 T1 ON T0.[TEAM] = T1.[TEAM] AND T0.[LEVEL] = T1.[LEVEL] 
FULL JOIN TABLE1 T2 ON T0.[TEAM] = T2.[TEAM] AND T0.[LEVEL] = T2.[LEVEL] 

問題是,我不知道該輸入表,並採取所有這些表從用戶在運行時輸入並執行加入。我無法一次合併兩個表,因爲我的表在技術上可以一次合併三個以上的表(最多9個或10個)。

如何確保我從所有表中獲取所有記錄(使用完全外部聯接),但不會像#1中那樣獲得兩行。

+0

我現在沒有時間爲此生成查詢,但也許您應該*真的*重新考慮您的數據庫結構。 – yaauie 2009-01-14 04:51:22

+0

+1重新思考數據模型 – 2009-01-14 05:20:18

回答

0

這就是FULL OUTER JOIN的定義(使用時,幾乎總是暗示糟糕的設計 - 我每年大約使用一次FULL OUTER JOIN)。

也許如果你給出了你正在尋找的結果?

我在想UNION,GROUP BY和COALESCE。

3

如果這是你需要的東西:

TEAM LEVEL Value1 Value2 Value3 
A 1  1  NULL NULL 
B 1  NULL 1000 900 

然後你就可以實現與以下:

SELECT [TEAM], [LEVEL], MAX(v1) Value1, MAX(v2) Value2, MAX(v3) Value3 
FROM (
    SELECT [TEAM], [LEVEL], Value1 v1, NULL v2, NULL v3 
    FROM TABLE1 
    UNION 
    SELECT [TEAM], [LEVEL], NULL, Value2, NULL 
    FROM TABLE2 
    UNION 
    SELECT [TEAM], [LEVEL], NULL, NULL, Value3 
    FROM TABLE3 
) t0 
GROUP BY [TEAM], [LEVEL] 

,並根據您的需要,你可以使用盡可能多的表。

0

您需要的是在第二個連接表達式上添加一個附加匹配條件,以允許它匹配第二個表的團隊/級別值。我還使用ISNULL簡化了團隊/等級列表達式:

SELECT DISTINCT 
    ISNULL(T0.[TEAM],ISNULL(T1.[TEAM],T2.[TEAM])) AS [TEAM], 
    ISNULL(T0.[LEVEL],ISNULL(T1.[LEVEL],T2.[LEVEL])) AS [LEVEL], 
    T0.[VALUE1], T1.[VALUE2], T2.[VALUE3]  
FROM TABLE1 T0 
FULL JOIN TABLE2 T1 ON T0.[TEAM] = T1.[TEAM] AND T0.[LEVEL] = T1.[LEVEL] 
FULL JOIN TABLE3 T2 ON (T0.[TEAM] = T2.[TEAM] AND T0.[LEVEL] = T2.[LEVEL]) 
        OR (T1.[TEAM] = T2.[TEAM] AND T1.[LEVEL] = T2.[LEVEL]) 

請參閱? T1沒有顯示在與T2相同的行上,因爲你從來沒有把它作爲匹配的可能性。

0

因爲你在yru查詢中定義了不同的意思,這意味着在這個聯合中沿着一個多重入口所有使用都是最好的,因爲數據中有重複。

SELECT [TEAM], [LEVEL], MAX(v1) Value1, MAX(v2) Value2, MAX(v3) Value3 
FROM (
    SELECT [TEAM], [LEVEL], v1, NULL v2, NULL v3 
    FROM TABLE1 
    UNION ALL 
    SELECT [TEAM], [LEVEL], NULL v1, V2, NULL v3 
    FROM TABLE2 
    UNION ALL 
    SELECT [TEAM], [LEVEL], NULL V1, NULL V2, V3 
    FROM TABLE3 
) t0 
GROUP BY [TEAM], [LEVEL]