不使用左连接,使用3个表进行左连接

3

我必须使用 left join 从3个表中获取所有数据。我已经尝试使用和不使用 left join 来实现。但是我的老师要求使用只有 inner join 的另一种解决方案。我无法找到这个解决方案,请给予一些建议。以下是这些表:

enter image description here

结果应该如下所示:

enter image description here

使用左连接的解决方案:
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

这个链接应该可以帮助你解决问题:https://dev59.com/NlvUa4cB1Zd3GeqPuYQa - Vladimir S.
1
@TimBiegeleisen 是的,但他特别要求内连接。 - SQL Police
@SQLGeorge 是的,他希望我们只使用内连接。 - Ogün ADSAY
@VladimirS。那个问题中有两个表,我有三个表。 - Ogün ADSAY
@OgünADSAY 我在下面给出了一种可能的解决方案。基本上,您首先通过进行“INNER JOIN”来开始,然后添加回通过获取所有表的内积而被删除的结果集的部分。 - Tim Biegeleisen
显示剩余2条评论
2个回答

3
这里有一种方法,只使用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


这个链接可以帮助你在IT技术上更好的理解。

@MartinSmith 我从他最初的查询开始,然后进行了修改以获得答案。我忘记删除 LEFT JOIN - Tim Biegeleisen
它只返回了5行,应该是9行。 - Ogün ADSAY
谢谢。我必须提到他说可以用一个SELECT语句完成,但我不知道怎么做 :) - Ogün ADSAY
天啊,我不知道是否应该将这个作为结果给他:D 无论如何,非常感谢。 - Ogün ADSAY
@TimBiegeleisen,一开始我没有正确地阅读数据。我没有注意到订单表中的某些customers_id和parts_id在它们各自的表中不存在...当我使用了你的fiddle后才意识到这一点。 - Thomas G
显示剩余6条评论

1
这在“现实生活”中没有意义,但我理解它在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

抱歉,错误信息156,级别15,状态1,第23行。 关键字“ORDER”附近语法不正确。 - Ogün ADSAY
它的,不是它的(请注意区分“它的”与“它是”的区别) - SQL Police
抱歉还是不行。我想我们不能在FROM子句中编写SELECT语句, Msg 102,级别15,状态1,第21行 附近存在语法错误“)”。 - Ogün ADSAY
该死,它应该能工作!尝试删除主查询“SELECT * FROM()ORDER BY”,只保留3个嵌套查询,这是最重要的。 - Thomas G
我没有点踩。我从来不会给任何人点踩 :) 只是为了努力付出而点赞 :) - Ogün ADSAY
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接