SQL - 完全外连接

时间:2017-03-18 11:02:10

标签: sql sql-server join

我在sql数据库中有三个表

enter image description here

我需要加入这三个表来获得这样的表

enter image description here

我想加入三个表来获取整个第一,第三和第二(其中sort为2)表的所有数据

我尝试这个查询

  select table1.Item, table1.Location, table1.Type,
         table2.Item, table2.Location, table2.Type,table2.Sort
         table3.Item, table3.Location, table3.Type
   from table1
 full outer join table2
  on table1.Item = table2.Item
  and table1.Location = table2.Location
  and table1.Type = table2.Type
  and table2.Sort = '2'
 full outer join table3
  on table1.Item = table3.Item
  and table1.Location = table3.Location
  and table1.Type = table3.Type

但我只得到这张表

enter image description here

如何使用所有组合进行查询以获得我想要的表格?

有什么想法吗?

4 个答案:

答案 0 :(得分:5)

您的方法是正确的,您所缺少的就是在第二个加入标准中使用coalesce

第一个outer join会返回一组包含null个值的行,如果您在第三个join个标准中使用这些值,则该条件不会满意。

您可以使用coalesce解决此问题,如果第一个参数为null

,则会使用第二个参数
select  table1.Item, table1.Location, table1.Type,
        table2.Item, table2.Location, table2.Type,table2.Sort
        table3.Item, table3.Location, table3.Type
from    table1
full outer join table2
on      table1.Item = table2.Item and
        table1.Location = table2.Location and
        table1.Type = table2.Type
full outer join table3
on      coalesce(table1.Item, table2.Item) = table3.Item and
        coalesce(table1.Location, table2.Location) = table3.Location and
        coalesce(table1.Type, table2.Type) = table3.Type
where   coalesce(table2.Sort, 2) = 2

答案 1 :(得分:3)

select table1.Item, table1.Location, table1.Type,
       table2.Item, table2.Location, table2.Type, table2.Sort,
       table3.Item, table3.Location, table3.Type
from table1
  full outer join table3
    on  table1.Item = table3.Item
   and table1.Location = table3.Location
   and table1.Type = table3.Type
  full outer join table2
    on (table1.Item = table2.Item
   and table1.Location = table2.Location
   and table1.Type = table2.Type
   and table2.Sort = '2'
   )
   or (table3.Item = table2.Item
   and table3.Location = table2.Location
   and table3.Type = table2.Type
   and table2.Sort = '2'
   )
where (table2.Sort = '2' or table2.Sort is null)

rextester演示:http://rextester.com/MNW25175

结果

+------+----------+-------+------+----------+-------+------+------+----------+-------+
| Item | Location | Type  | Item | Location | Type  | Sort | Item | Location | Type  |
+------+----------+-------+------+----------+-------+------+------+----------+-------+
| 123  | A        | small | NULL | NULL     | NULL  | NULL | 123  | A        | small |
| NULL | NULL     | NULL  | 123  | A        | big   | 2    | 123  | A        | big   |
| NULL | NULL     | NULL  | 123  | B        | small | 2    | NULL | NULL     | NULL  |
+------+----------+-------+------+----------+-------+------+------+----------+-------+

这也有效,但只是因为table2table1中的所有行匹配,这可能不符合您的实际用例:

select table1.Item, table1.Location, table1.Type,
       table2.Item, table2.Location, table2.Type, table2.Sort,
       table3.Item, table3.Location, table3.Type
from table1
  full outer join table3
    on  table1.Item = table3.Item
   and table1.Location = table3.Location
   and table1.Type = table3.Type
  full outer join table2
    on table3.Item = table2.Item
   and table3.Location = table2.Location
   and table3.Type = table2.Type
   and table2.Sort = '2'
where (table2.Sort = '2' or table2.Sort is null)

答案 2 :(得分:1)

使用LEFT OUTER JOIN:

 SELECT *  FROM Table 2 
 LEFT OUTER JOIN Table 1 ON table1.Item = table2.Item AND  table1.Location =  
                  table2.Location AND table1.Type = table2.Type and 
                  table2.Sort = '2'
 LEFT OUTER JOIN Table 3 ON table1.Item = table3.Item
                 and table1.Location = table3.Location
                 and table1.Type = table3.Type 

答案 3 :(得分:1)

您可以通过以下查询获得所需的结果

SELECT d.item, d.location, d.[type],
    s.item, s.location, s.[type], s.sort,
    h.item, h.location, h.[type]
FROM tblData d
    FULL OUTER JOIN tblSearchData s
        ON d.item = s.item 
        AND d.location = s.location
        AND d.[type] = s.[type]
    FULL OUTER JOIN tblHelpData h
        ON (s.item = h.item OR d.item=h.item)
        AND (s.location = h.location OR d.location=h.location)
        AND (s.[type] = h.[type] OR d.[type]=h.[type])
WHERE s.sort=2 OR s.sort IS NULL