在不使用“左连接”的情况下模拟左连接

时间:2012-02-06 11:57:01

标签: sql

我需要在不使用“左连接”键的情况下模拟左连接效果。

我有两个表,A和B,都有idname列。我想在两个表中选择所有dbid,其中A中的名称等于B中的名称。

我使用它来进行同步,所以在开始时B是空的(所以我将从A中获取带有id的id的夫妻,并且来自B的id为null)。后来我会混合价值和价值的夫妻 - 无效。

通常情况是:

SELECT A.id, B.id
FROM A left join B
ON A.name = B.name

问题在于我无法使用left join并且想知道是否/如何做同样的事情。

10 个答案:

答案 0 :(得分:17)

只需反转表并使用右连接。

SELECT A.id,
       B.id
FROM   B
       RIGHT JOIN A
         ON A.name = B.name  

答案 1 :(得分:13)

您可以使用此方法,但必须确保内部选择仅返回一行。

SELECT A.id, 
(select B.id from B where  A.name = B.name) as B_ID
FROM A 

答案 2 :(得分:12)

我不熟悉java / jpa。使用纯SQL,这是一种方法:

SELECT A.id AS A_id, B.id AS B_id
  FROM A INNER JOIN B
          ON A.name = B.name
UNION
SELECT id AS A_id, NULL AS B_id 
  FROM A 
 WHERE name NOT IN ( SELECT name FROM B );

答案 3 :(得分:6)

例如,在SQL Server中,您可以使用*=运算符进行左连接:

select A.id, B.id
from A, B
where A.name *= B.name

如果存在这样的运算符,则其他数据库的语法可能略有不同。

这是在引入join关键字之前使用的旧语法。当然,如果可能,您应该使用join关键字。旧语法甚至可能不适用于较新版本的数据库。

答案 4 :(得分:4)

您可以使用子查询,例如:

select a.id
,      nvl((select b.id from b where b.name = a.name), "") as bId
from a

答案 5 :(得分:4)

到目前为止,我只能想到两种尚未给出的方法。我的最后三个想法已经给出了(boohoo),但我把它们放在这里供后人使用。我没有作弊就想到了他们。 :-P

  1. 计算B是否匹配,然后为B集提供额外的UNIONed行,以便在没有匹配时提供NULL。

    SELECT A.Id, A.Something, B.Id, B.Whatever, B.SomethingElse
    FROM
       (
          SELECT
             A.*,
             CASE
                WHEN EXISTS (SELECT * FROM B WHERE A.Id = B.Id) THEN 1
                ELSE 0
             END Which
          FROM A
       ) A
       INNER JOIN (
          SELECT 1 Which, B.* FROM B
          UNION ALL SELECT 0, B* FROM B WHERE 1 = 0
       ) B ON A.Which = B.Which
          AND (
             A.Which = 0
             OR (
                A.Which = 1
                AND A.Id = b.Id
             )
          )
    
  2. 对同一查询略有不同:

    SELECT A.Id, B.Id
    FROM
       (
          SELECT
             A.*,
             CASE
                WHEN EXISTS (SELECT * FROM B WHERE A.Id = B.Id) THEN A.Id
                ELSE -1 // a value that doesn't exist in B
             END PseudoId
          FROM A
       ) A
       INNER JOIN (
          SELECT B.Id PseudoId, B.Id FROM B
          UNION ALL SELECT -1, NULL
       ) B ON A.Which = B.Which
          AND A.PseudoId = B.PseudoId
    
  3. 仅适用于SQL Server。我知道,它实际上是一个左连接,但它不会在那里说出LEFT

    SELECT A.Id, B.Id
    FROM
       A
       OUTER APPLY (
          SELECT *
          FROM B
          WHERE A.Id = B.Id
       ) B
    
  4. 获取内连接,然后获取UNION外连接:

    SELECT A.Id, B.Id
    FROM
       A
       INNER JOIN B ON A.name = B.name
    UNION ALL 
    SELECT A.Id, NULL
    FROM A
    WHERE NOT EXISTS (
       SELECT *
       FROM B
       WHERE A.Id = B.Id
    )
    
  5. 使用RIGHT JOIN。那不是LEFT JOIN!

    SELECT A.Id, B.Id
    FROM
       B
       RIGHT JOIN A ON B.name = A.name
    
  6. 只需在子查询表达式中选择B值(我们希望每个A只有一个B)。 B中的多列可以是他们自己的表达式(YUCKO!):

    SELECT A.Id, (SELECT TOP 1 B.Id FROM B WHERE A.Id = B.Id) Bid
    FROM A
    
  7. 任何使用Oracle的人都可能在任何没有FROM的SELECT中需要一些FROM DUAL子句。

答案 6 :(得分:2)

你可以使用oracle + operator进行左连接: -

SELECT A.id,B.id 从A,B ON A.name = B.name(+)

查找链接: -

Oracle "(+)" Operator

答案 7 :(得分:1)

SELECT A.id, B.id
FROM A full outer join B
ON A.name = B.name
where A.name is not null

答案 8 :(得分:0)

我不确定您是否只能使用LEFT JOIN,或者您是否被限制使用任何JOINS。但据我了解您的要求,INNER JOIN应该有效:

SELECT A.id, B.id
FROM A 
INNER JOIN B ON A.name = B.name

答案 9 :(得分:0)

使用纯粹的简单sql模拟左连接:

SELECT A.name
FROM A
where (select count(B.name) from B where  A.id = B.id)<1; 

在左连接中,B中没有引用A的行,因此B中的0个名称将引用A中没有匹配的行 +或A.id = B.id在where子句中模拟内连接