2016-01-25 34 views
2

我想將兩個表連接在一起。第一個表格包含我不想複製的數據記錄。我加入到第一個表的第二個表中,用[profileId]和[role]查找[value]。第二個表中的[profileId],[role]列對組合有一個唯一的約束,但[role]有時可以是NULL,在這種情況下,我將該值視爲該配置文件的默認值。加入SQLES與條件是重複行

如何將這些表連接在一起而不重複行,並且不使用多個左連接?我的實際查詢比例子更復雜。

請參閱下面的示例。

DECLARE @temp TABLE ([profileId] int, [role] int) 
DECLARE @temp2 TABLE ([profileId] int, [role] int, [value] nvarchar(50)) 

INSERT INTO @temp ([profileId], [role]) VALUES (1, 1) 
INSERT INTO @temp ([profileId], [role]) VALUES (1, 2) 
INSERT INTO @temp ([profileId], [role]) VALUES (2, 1) 
INSERT INTO @temp ([profileId], [role]) VALUES (2, 2) 
INSERT INTO @temp2 ([profileId], [role], [value]) VALUES (1, 1, 'MATCH') 
INSERT INTO @temp2 ([profileId], [role], [value]) VALUES (1, NULL, 'DEFAULT1') 
INSERT INTO @temp2 ([profileId], [role], [value]) VALUES (2, NULL, 'DEFAULT2') 

SELECT 
    T1.[profileId], 
    T1.[role], 
    T2.value 
FROM 
    @temp T1 
    JOIN @temp2 T2 ON T1.profileId = T2.profileId AND COALESCE(T2.[role], T1.[role]) = T1.[role] 

這給了我(我明白爲什麼)

================================ 
| profileId | role | value | 
================================ 
|  1  | 1 | MATCH | 
-------------------------------- 
|  1  | 1 | DEFAULT1 | 
-------------------------------- 
|  1  | 2 | DEFAULT1 | 
-------------------------------- 
|  2  | 1 | DEFAULT2 | 
-------------------------------- 
|  2  | 2 | DEFAULT2 | 
================================ 

雖然我想

================================ 
| profileId | role | value | 
================================ 
|  1  | 1 | MATCH | 
-------------------------------- 
|  1  | 2 | DEFAULT1 | 
-------------------------------- 
|  2  | 1 | DEFAULT2 | 
-------------------------------- 
|  2  | 2 | DEFAULT2 | 
================================ 
+0

您的默認值是在數據庫中,還是可以使用'CASE'來獲取? –

+0

'@ temp2'中會有多個NULL'role'嗎? –

+0

@FelixPamittan是的,根據我的回答評論。還有一些'profileID' –

回答

1

您可以使用APPLYTOP

SELECT 
    t.profileId, 
    t.role, 
    x.value 
FROM @temp t 
OUTER APPLY(
    SELECT TOP 1 value 
    FROM @temp2 
    WHERE 
     profileId = t.profileId 
     AND (role = t.role OR role IS NULL) 
    ORDER BY 
     CASE WHEN role IS NOT NULL THEN 0 ELSE 1 END 
)x 
0

,如果你知道DEFAULT值使用left join

SQL Fiddle Demo

SELECT 
    T1.[role], 
    COALESCE(T2.value, 'DEFAULT') as value 
FROM 
    temp T1 
LEFT JOIN temp2 T2 
     ON T1.[role] = T2.[role]; 

否則

SELECT 
    T1.[role], 
    COALESCE(T2.value, (SELECT value 
         FROM temp2 
         WHERE role is NULL and temp2.profileID = T1.profileID)) as value 
FROM 
    temp T1 
LEFT JOIN temp2 T2 
     ON T1.[role] = T2.[role] 
     AND T1.[profileID] = T2.[profileID] 
     ; 
+0

[值]是用戶可編輯的,所以我不知道DEFAULT。另外,我將修改@ temp2的定義,以明確有很多DEFAULT值(基於profileID)。 – ben

+0

然後使用第二個版本。 –

2

這個SQL工作正常:

SELECT 
    T1.[role], 
    Value = coalesce(max(nullif(T2.value,'DEFAULT')),'DEFAULT') 
FROM 
    @temp T1 
    JOIN @temp2 T2 ON COALESCE(T2.[role], T1.[role]) = T1.[role] 
group by 
    T1.[role] 
;