【问题标题】:How do I force join inside a left join branch?如何在左连接分支内强制连接?
【发布时间】:2010-11-19 18:20:47
【问题描述】:

我需要 LEFT 加入整个 t2+t3 分支,但如果我能在 t1 和 t2 之间找到匹配的连接,我想强制执行 t2 和 t3 连接。

   SELECT T1.name,T2.bob,T3.a
     FROM T1
LEFT JOIN T2 ON t1.id = t2.t1_id
     JOIN T3 ON t2.id = T3.t2_id

语法是什么?

样本数据:

T1 [id,name]
1 aaa
2 bbb
3 ccc

T2 [id,t1_id,bob]
1,1,777
2,1,888
2,2,999

T3[id,t2_id,a]
1,2,'yeh'

预期结果:

 [name] , [a]   , [bob]
  aaa   , 'yeh' , 888
  bbb   , NULL  , NULL
  ccc   , NULL  , NULL

【问题讨论】:

  • 那么您要排除 [a] 不为 NULL 且 [bob] 为 NULL 的行吗?
  • @Lynette Duffy - 不......这有点像 AND 语句。要么我得到 [A] AND [bob] 要么我没有得到(null,null)。不想在没有 [bob] 的情况下获得 [a],反之亦然。

标签: sql mysql join left-join


【解决方案1】:

EDIT:此查询返回您预期的示例数据的结果 - (另请注意,此查询是在下面 Treefrog 的回答的帮助下进行的)-

SELECT t1.[name], t3.a, t2.bob
FROM T2 as t2
JOIN T3 as t3 ON t3.t2_id = t2.id
RIGHT JOIN T1 as t1 ON t1.id = t2.t1_id

我的旧答案 -

SELECT a
FROM T1 as t1
INNER JOIN T2 as t2 ON t1.id = t2.t1_id
LEFT JOIN T3 as t3 ON t2.id = t3.t2_id

【讨论】:

  • 对不起,但不,这不会强制 t2 和 t3 的连接只有在它们都有数据时才有效。
  • 有些人忘记了我们不是心灵感应 :(
  • @Italy Maov - 编辑了我的答案。我也想在这里帮助你。你不必对我投反对票。如果你觉得它不对,那么你可以让我知道。如果没有帮助,将尝试更正或删除它。
  • @Sachin Shanbhag - 查看已编辑的问题,我取消了我的反对票(我真的认为反对票不是个人的,只是标记错误的答案,如果我冒犯了你,对不起)。
  • thx,这个答案正是我所需要的......为了简单的答案而投票赞成,从来没有改变和使用正确的连接
【解决方案2】:
SELECT T1.a
FROM T2
JOIN T3 ON T3.t2_id = T2.id
RIGHT JOIN T1 ON T1.id = T2.t1_id

【讨论】:

    【解决方案3】:

    这两个都会给你你的结果。不确定哪个会更好。

    嵌套语句:

    SELECT [name], NULL AS [a], NULL AS  [bob]
    FROM t1
    LEFT OUTER JOIN t2 ON t1.id = t2.t1_id
    LEFT OUTER JOIN t3 ON t2.id = t3.t2_id 
    WHERE t3.t2_id IS NULL
    AND (SELECT COUNT(*) FROM t1 AS t1b LEFT OUTER JOIN t2 AS t2b ON t1b.id = t2b.t1_id LEFT OUTER JOIN t3 AS t3b ON t2b.id = t3b.t2_id WHERE t1.id = t1b.id AND t3b.a IS NOT NULL) = 0
    UNION
    SELECT [name], [a], [bob]
    FROM t1
    LEFT OUTER JOIN t2 ON t1.id = t2.t1_id
    LEFT OUTER JOIN t3 ON t2.id = t3.t2_id 
    WHERE t3.t2_id IS NOT NULL
    ORDER BY t1.name
    

    临时表:

    CREATE TABLE #tmp_Rslt([name] varchar(50), [a] varchar(50), [bob] varchar(50))
    
    --select matches
    INSERT INTO #tmp_Rslt
    SELECT [name], [a], [bob]
    FROM t1
    LEFT OUTER JOIN t2 ON t1.id = t2.t1_id
    LEFT OUTER JOIN t3 ON t2.id = t3.t2_id 
    WHERE t3.t2_id IS NOT NULL
    ORDER BY t1.name
    
    --select t1's that didn't have matches
    INSERT INTO #tmp_Rslt
    SELECT [name], NULL AS [a], NULL AS  [bob]
    FROM t1
    LEFT OUTER JOIN t2 ON t1.id = t2.t1_id
    LEFT OUTER JOIN t3 ON t2.id = t3.t2_id 
    WHERE t3.t2_id IS NULL
    AND t1.[name] NOT IN (SELECT DISTINCT [name] FROM #tmp_Rslt)
    
    SELECT *
    FROM #tmp_Rslt
    
    --cleanup.
    DROP TABLE #tmp_Rslt
    

    【讨论】:

      【解决方案4】:

      这应该在 MySQL 中工作

      SELECT * FROM T1
      LEFT JOIN (T2
       INNER JOIN T3 ON T2.id=T3.t2_id
      ) ON T1.id= T2.t1_id
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-30
        • 2016-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-16
        相关资源
        最近更新 更多