【问题标题】:TSQL Left and Inner Joins [duplicate]TSQL左连接和内连接[重复]
【发布时间】:2018-03-09 14:03:06
【问题描述】:

给定以下示例数据:

CREATE TABLE People(PeopleID int, Name varchar(10))
INSERT INTO People VALUES(1, 'Chris')
INSERT INTO People VALUES(2, 'Cliff')
INSERT INTO People VALUES(3, 'Heather')

CREATE TABLE Things(ThingID int, ThingName varchar(10))
INSERT INTO Things VALUES(14, 'Bike')
INSERT INTO Things VALUES(17, 'Trailer')
INSERT INTO Things VALUES(18, 'Boat')

CREATE TABLE PeopleThings(PeopleID int, ThingID int)
INSERT INTO PeopleThings VALUES(1, 18)
INSERT INTO PeopleThings VALUES(2, 14)

...以及以下查询:

SELECT P.Name,
     T.ThingName
FROM People P
    LEFT OUTER JOIN PeopleThings PT ON P.PeopleID = PT.PeopleID
    INNER JOIN Things T ON PT.ThingID = T.ThingID

我希望看到以下结果:

|Name      |ThingName |
-----------------------
|Chris     |Boat      |
-----------------------
|Cliff     |Bike      |
-----------------------
|Heather   |(null)    |
-----------------------

我想要 PEOPLE 表中每个人的列表,以及他们拥有的事物的名称(或者如果他们拥有任何东西)。我知道问题出在我的 JOIN 中,但我不明白/看不到哪里。请帮忙。

【问题讨论】:

  • 这是我总是将内部连接写成相邻的原因之一。它基本上在逻辑上构建了一个越来越小的集合。左连接总是在那之后,只要您不在 WHERE 子句中放置引用,就不会减少集合大小。我个人认为这种模式可以有效地防止此类问题。
  • ON PT.ThingID 中断左连接。
  • 嗨。了解左连接返回什么——内连接行加上由空值扩展的不匹配左表行。如果你在外连接之后进行内连接,你只会从内连接中得到通常的结果——由满足 on 的两个输入组成的行。

标签: tsql left-join inner-join


【解决方案1】:

您已经有了答案,但我正在努力解决它
INNER JOIN Things T ON PT.ThingID 打破了左连接

您可以保留inner join,但更改on 的顺序。
这可能比 2 left join 更有效。

declare @People TABLE (PeopleID int primary key, Name varchar(10));
INSERT INTO @People VALUES
       (1, 'Chris')
     , (2, 'Cliff')
     , (3, 'Heather');

declare @Things TABLE (ThingID int primary key, ThingName varchar(10))
INSERT INTO @Things VALUES
       (14, 'Bike')
     , (17, 'Trailer')
     , (18, 'Boat');

declare @PeopleThings TABLE (PeopleID int, ThingID int, primary key (PeopleID, ThingID));
INSERT INTO @PeopleThings VALUES
       (1, 18)
     , (1, 17)
     , (2, 14);

SELECT P.Name, T.ThingName
FROM @People P
LEFT JOIN @PeopleThings PT   
     JOIN @Things T 
       ON PT.ThingID = T.ThingID 
  ON P.PeopleID = PT.PeopleID
order by P.Name, t.ThingName;

Name       ThingName
---------- ----------
Chris      Boat
Chris      Trailer
Cliff      Bike
Heather    NULL

也可以通过右连接来做到这一点

SELECT P.Name, T.ThingName
FROM @PeopleThings PT
JOIN @Things T 
  ON PT.ThingID = T.ThingID 
right join @People P 
  ON P.PeopleID = PT.PeopleID 
order by P.Name, t.ThingName;

【讨论】:

    【解决方案2】:

    这将修复您的查询:

    SELECT P.Name,
         T.ThingName
    FROM People P
        LEFT OUTER JOIN PeopleThings PT ON P.PeopleID = PT.PeopleID
        LEFT OUTER JOIN Things T ON PT.ThingID = T.ThingID;
    

    【讨论】:

      猜你喜欢
      • 2018-03-06
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 2015-03-04
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多