如何在SQL中替换左连接

时间:2011-09-22 06:29:57

标签: sql left-join

任何人都可以告诉我如何在不使用左连接的情况下编写等效的左连接。

Select * from a left join b on a.name = b.name.

3 个答案:

答案 0 :(得分:10)

请记住,SQL的外连接是一种关系联合,它专门用于投影空值。如果你想避免使用null值(在我看来是一件好事),你应该避免使用外连接。请注意,现代关系语言完全没有使用null和outer连接的概念。

此外部联接:

SELECT DISTINCT T1.id, T1.value, T2.other_value
  FROM T1
       LEFT OUTER JOIN T2
          ON T1.id = T2.id;

...在语义上等同于此SQL代码:

SELECT T1.id, T1.value, T2.other_value
  FROM T1
       INNER JOIN T2
          ON T1.id = T2.id
UNION
SELECT T1.id, T1.value, NULL
  FROM T1
 WHERE NOT EXISTS (
                   SELECT * 
                     FROM T2
                    WHERE T1.id = T2.id
                  );

第二个查询可能看起来很长,但这只是因为SQL的设计/演变方式。以上只是一个自然的联合,一个联盟和一个半联盟。但是,SQL没有semijoin运算符,如果您的产品没有实现标准SQL的SELECT语法,则要求您在JOIN子句中指定列列表并编写NATURAL JOIN子句,这会导致很多代码表达的东西很简单。

因此,您可以编写代码,例如上面的第二个查询,但使用实际的默认值而不是空值。

答案 1 :(得分:1)

虽然左外连接是建议的编写sql的方式与替代方法相比,但我们仍然可以通过使用union为结果集实现左外连接。如果我们有两个表Table1和表2,那么我们可以通过以下方式实现这一点 -

select
       A.Id, 
       A.Col1, 
       A.Col2, 
       A.Col3, 
       B.Id Col4, 
       B.Col1 Col5, 
       B.Col2 Col6, 
       B.Col3 Col7, 
       B.Col4 Col8
from   Table1 A, Table2 B
where  A.Id = B.Id

union all

select
       A.Id, 
       A.Col1, 
       A.Col2, 
       A.Col3, 
       null as Col4, 
       null as Col5, 
       null as Col6, 
       null as Col7, 
       null as Col8
from   Table1 A
where  not exists(select 1 from Table2 B where B.Id = A.Id)

这将有助于实现相同的结果,但由于使用了Union,如果表格很大,可能会出现一些性能问题。

答案 2 :(得分:0)

Oracle伪装左连接:

SELECT * FROM A, B
 WHERE a.name = b.name(+)

通用:

SELECT a.*, case c.existence WHEN 1 then c.name ELSE NULL END
  FROM A
 INNER JOIN ( SELECT name name, 1 existence FROM B
               UNION ALL
              SELECT a.name name, 0 existence FROM A
               WHERE a.name NOT IN ( SELECT name FROM B )
            ) C
    ON c.name = a.name