2013-07-17 2 views
0

У меня есть два вида источника:T-SQL множественным внешнее соединение с композитным ключом

View1 

----------------------------------------------------- 
| UserId | RoleId | Total1 (calculated value) | 
----------------------------------------------------- 
| 1  | 21 |   9    | 
----------------------------------------------------- 
| 1  | 22 |   5    | 
----------------------------------------------------- 
| 2  | 21 |   7    | 
----------------------------------------------------- 
| 4  | 23 |   4    | 
----------------------------------------------------- 

View2 

----------------------------------------------------- 
| UserId | RoleId | Total2 (calculated value) | 
----------------------------------------------------- 
| 1  | 21 |   2    | 
----------------------------------------------------- 
| 1  | 24 |   1    | 
----------------------------------------------------- 
| 3  | 21 |   3    | 
----------------------------------------------------- 
| 4  | 21 |   4    | 
----------------------------------------------------- 

Предпочтительный выход основан на UserId И Идентификатор роли равенства:

--------------------------------------------- 
| UserId | RoleId | Total1 | Total2 | 
--------------------------------------------- 
| 1  | 21 |  9 | 2  | 
--------------------------------------------- 
| 1  | 22 |  5 | NULL | 
--------------------------------------------- 
| 1  | 24 | NULL | 1  | 
--------------------------------------------- 
| 2  | 21 |  7 | NULL | 
--------------------------------------------- 
| 3  | 21 | NULL | 3  | 
--------------------------------------------- 
| ... | ... | ... | ... | 

Насколько я знаю, что я должен использовать некоторый тип ВЗГЛЯДНЫХ ОБЪЕДИНЕНИЙ - но как?

ответ

3
SELECT 
    ISNULL(v1.UserID,v2.UserID) as UserID, 
    ISNULL(v1.RoleID,v2.RoleID) as RoleID, 
    v1.Total1 , 
    v2.Total2 
FROM view1 v1 
FULL OUTER JOIN view2 v2 
ON v1.UserID = v2.UserID 
AND v1.RoleID = v2.RoleID 
2

Предполагая, что существует только одна соответствующая строка из каждой таблицы, вы должны использовать FULL OUTER JOIN:

SELECT COALESCE(v1.UserId, v2.UserId) AS UserId, 
    COALESCE(v1.RoleId, v2.RoleId) AS RoleId, 
    v1.Total1 
    v2.Total2 
FROM View1 v1 
FULL OUTER JOIN View2 v2 ON v1.UserId = v2.UserId AND v1.RoleId = v2.RoleId 

В качестве альтернативы, можно использовать UNION и SUM результаты, особенно полезно, если строки не уникальны для каждой таблицы, и соединение будет производить дублирование:

SELECT UserId, RoleId, SUM(Total1) AS Total1, SUM(Total2) AS Total2 
FROM 
(
    SELECT UserId, RoleId, Total1, NULL AS Total2 
    FROM View1 
    UNION ALL 
    SELECT UserId, RoleId, NULL AS Total1, Total2 
    FROM View2 
) Combined 
GROUP BY UserId, RoleId 
+0

+1 для полного внешнего соединения; большинство решений, которые я видел, основаны на союзе – OzrenTkalcecKrznaric

+0

Я в странной ситуации: оба решения работают отлично. Я попробовал сначала EricZ, чтобы он понял, но спасибо. и, конечно, +1. – boj

Смежные вопросы