【问题标题】:Left join without using left join with 3 tables不使用左连接的左连接与 3 个表
【发布时间】:2016-03-20 23:20:13
【问题描述】:

我必须使用left join 从 3 个表中获取所有数据。无论是否使用left join,我都这样做了。但是我的老师问了另一种只使用inner join 的解决方案。我只是找不到解决方案,请提供一些建议。以下是表格:

结果应该是这样的:

left join解决方案:

SELECT O.*,C.CUST_CODE,C.CUST_NAME,P.PART_CODE,P.PART_NAME 
FROM ORDERS O
LEFT OUTER JOIN PART P ON P.PART_ID = O.PART_ID
LEFT OUTER JOIN CUSTOMER C ON C.CUST_ID = O.CUST_ID

没有left join解决方案:

SELECT O.*,
(SELECT C.CUST_CODE FROM CUSTOMER C WHERE C.CUST_ID=O.CUST_ID) AS CUST_CODE,
(SELECT C.CUST_NAME FROM CUSTOMER C WHERE C.CUST_ID=O.CUST_ID) AS CUST_NAME,
(SELECT P.PART_CODE FROM PART P WHERE P.PART_ID = O.PART_ID ) AS PART_CODE,
(SELECT P.PART_NAME FROM PART P WHERE P.PART_ID = O.PART_ID ) AS PART_NAME
FROM ORDERS O

【问题讨论】:

  • 无法使用inner join 完成该结果。这是因为您的某些订单包含客户或零件的 NULL 值。你 100% 确定你的老师说 inner join 吗?
  • 这个链接应该可以帮助你解决你的问题stackoverflow.com/questions/7510481/…
  • @SQLGeorge 有几种方法可以在没有LEFT JOIN 的情况下执行此操作。这就是我相信 OP 所要求的。
  • @TimBiegeleisen 是的,但他专门要求内部连接。
  • @SQLGeorge 是的,他希望我们只使用内部联接

标签: sql sql-server join left-join inner-join


【解决方案1】:

这是一种仅使用INNER JOIN 而不在任何地方使用LEFT JOIN 的方法。它从使用INNER JOIN 而不是LEFT JOIN 的原始查询开始,然后将在获取所有表的内积时缺少的部分添加到该结果集中。

SELECT t.* FROM
(
    SELECT O.ORDER_ID, O.ORDER_DATE, C.CUST_CODE, C.CUST_NAME, P.PART_CODE, P.PART_NAME 
    FROM ORDERS O
    INNER JOIN PART P
        ON P.PART_ID = O.PART_ID
    INNER JOIN CUSTOMER C
        ON C.CUST_ID = O.CUST_ID
    UNION
    SELECT O.ORDER_ID, O.ORDER_DATE, NULL AS CUST_CODE, NULL AS CUST_NAME, P.PART_CODE,
        P.PART_NAME 
    FROM ORDERS O
    INNER JOIN PART P
        ON P.PART_ID = O.PART_ID
    WHERE O.CUST_ID NOT IN (SELECT C.CUST_ID FROM CUSTOMER C)
        OR O.CUST_ID IS NULL
    UNION
    SELECT O.ORDER_ID, O.ORDER_DATE, C.CUST_CODE, C.CUST_NAME, NULL AS PART_CODE,
        NULL AS PART_NAME 
    FROM ORDERS O
    INNER JOIN CUSTOMER C
        ON C.CUST_ID = O.CUST_ID
    WHERE O.PART_ID NOT IN (SELECT P.PART_ID FROM PART P)
        OR O.PART_ID IS NULL
    UNION
    SELECT O.ORDER_ID, O.ORDER_DATE, NULL AS CUST_CODE, NULL AS CUST_NAME,
        NULL AS PART_CODE, NULL AS PART_NAME
    FROM ORDERS O
    WHERE (O.CUST_ID NOT IN (SELECT C.CUST_ID FROM CUSTOMER C) AND
           O.PART_ID NOT IN (SELECT P.PART_ID FROM PART P)) OR
           (O.CUST_ID IS NULL AND O.PART_ID IS NULL)
) t
ORDER BY t.ORDER_ID ASC

点击以下链接查看工作演示:

SQLFiddle

【讨论】:

  • 先生在第一个 UNION 之前是 Left Join 本身的答案。我不明白你在这里做了什么?抱歉英语不好。
  • @MartinSmith 我从他的原始查询开始,然后修改它以获得答案。我忘了删除LEFT JOIN
  • 哦,天哪……是小提琴的时候了(咆哮)
  • 它只返回 5 行。它应该是 9 行
  • 谢谢。我不得不提一下,他说只需一个 SELECT 语句就可以完成。我不知道怎么做:)
【解决方案2】:

这在“现实生活”中没有意义,但我理解它在 SQL 课程中的意义。你有个好老师。

这样试试

SELECT * FROM
(   
    SELECT O.*,C.CUST_CODE,C.CUST_NAME,P.PART_CODE,P.PART_NAME 
    FROM ORDERS O
    INNER JOIN PART P ON P.PART_ID = O.PART_ID
    INNER JOIN CUSTOMER C ON C.CUST_ID = O.CUST_ID

    UNION

    SELECT O.*,NULL,NULL,P.PART_CODE,P.PART_NAME 
    FROM ORDERS O
    INNER JOIN PART P ON P.PART_ID = O.PART_ID
    WHERE O.CUST_ID IS NULL

    UNION

    SELECT O.*,C.CUST_CODE,C.CUST_NAME,NULL, NULL
    FROM ORDERS O
    INNER JOIN CUSTOMER C ON C.CUST_ID = O.CUST_ID
    WHERE O.PART_ID IS NULL

    UNION

    SELECT O.*,NULL,NULL,NULL, NULL
    FROM ORDERS O
    WHERE O.PART_ID IS NULL AND O.CUST_ID IS NULL   

)   T

ORDER BY ORDER_ID

【讨论】:

  • 是的,他是最棒的:)
  • 我发布时遗漏了一些内容,我在 30 秒后编辑了它。你试过最新版本吗?什么不起作用?
  • Nope, sorryMsg 156, Level 15, State 1, Line 23 关键字“ORDER”附近的语法不正确。
  • 它,不是它——请 ;)
  • 抱歉还是不行。我认为我们不能在 FROM、Msg 102、Level 15、State 1、Line 21 中写 SELECT ')' 附近的语法不正确。
猜你喜欢
  • 2020-07-28
  • 2014-10-29
  • 2011-10-01
  • 1970-01-01
  • 2014-02-04
  • 2016-08-31
  • 2019-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多