【问题标题】:SQL (SSMS) join all records from one table and second table but exclude 'duplicates' from secondSQL(SSMS)连接一个表和第二个表中的所有记录,但从第二个表中排除“重复”
【发布时间】:2021-04-21 15:11:11
【问题描述】:

我遇到了一个问题,我去了表 B 中的所有记录和表 A 中的任何不匹配记录,但它带回了表 A 中的匹配记录。还有另一个左连接到另一个表,该表被引入仅供参考。

我正在使用 SSMS v18。

所以 ID 将在表 A 和表 B 上。在 A 和 B 上会有多个此 ID 的记录,但如果日期/时间和 ID 在表 A 和表中相同,我不希望重复记录B.

例如- 我已经简化了我在下面使用的查询。

Select
    a.id
    a.datetime
    a.emp_id
    c.team_id
From 
    table_a as a
Left Join 
    table_b as b On a.id = b.id
                 And a.datetime <> b.datetime
Left Join 
    table_c On a.emp_id = c.emp_id

由于没有 NULL,我认为我不能使用它。我不相信完整的外部联接会返回我需要的东西。

有没有办法解决这个问题?联合查询解决方案将不起作用,因为表 A 和表 B 没有相同的列/列名。

如果需要更多信息,请告诉我。

编辑 - 附加 抱歉,但现在要求发生了变化,我现在需要删除匹配的记录,而不是只删除重复项。有没有办法解决这个问题?

其他 - 数据示例

表 A:

+----+------------------+--------+
| Id |     Datetime     | emp_id |
+----+------------------+--------+
|  1 | 20/04/2021 10:30 | a      |
|  1 | 20/04/2021 11:15 | a      |
|  2 | 21/04/2021 12:10 | b      |
|  2 | 21/04/2021 13:20 | b      |
|  2 | 22/04/2021 15:30 | c      |
|  3 | 23/04/2021 09:45 | d      |
|  4 | 23/04/2021 14:35 | e      |
+----+------------------+--------+

表 B:

+----+------------------+-------------+
| Id |     Datetime     | other_field |
+----+------------------+-------------+
|  1 | 20/04/2021 10:30 | x           |
|  2 | 21/04/2021 13:20 | y           |
|  4 | 23/04/2021 14:35 | z           |
+----+------------------+-------------+

所需的输出:

+----+------------------+--------+---------+
| Id |     Datetime     | emp_id | team_id |
+----+------------------+--------+---------+
|  1 | 20/04/2021 11:15 | a      | team_01 |
|  2 | 21/04/2021 12:10 | b      | team_02 |
|  2 | 22/04/2021 15:30 | c      | team_01 |
|  3 | 23/04/2021 09:45 | d      | team_02 |
+----+------------------+--------+---------+

因此,表 B 中的重复 ID 和日期时间不会显示在最终输出中(不管任何其他字段)

【问题讨论】:

  • 样本数据和期望的结果会有所帮助。例如,您的问题描述没有提到 TableC。
  • 如果您可以为每个表创建示例数据,那么您就可以针对各种情况展示您想要的行为和结果。目前来说太笼统和模棱两可了……stackoverflow.com/help/minimal-reproducible-example

标签: sql-server ssms


【解决方案1】:

您似乎需要右连接而不是左连接。左连接将带回表 A 中的所有行,以及表 B 中与您提供的条件匹配的所有行。您似乎想要表 B 中的所有内容,这需要右连接。

我知道有些开发人员讨厌右连接,如果你有这种感觉,你可以简单地切换查询中表的顺序,让表 B 首先列出,左连接到表 A。我觉得第一个解决方案比较简单,但您需要熟悉它。

这是我的解决方案,按我上面提到的顺序列出。

Select
     a.id
    ,a.datetime
    ,a.emp_id
    ,c.team_id
From 
    table_a as a
RIGHT Join  -- here is my change 
    table_b as b On a.id = b.id
                 And a.datetime <> b.datetime
Left Join 
    table_c On a.emp_id = c.emp_id;


/*solution II*/

Select
     a.id
    ,a.datetime
    ,a.emp_id
    ,c.team_id
From 
    table_b as b
Left Join  
    table_a as a On a.id = b.id
                 And a.datetime <> b.datetime
Left Join 
    table_c On a.emp_id = c.emp_id;

/*Updated solution, based on the comments (requirements seem to have changed)*/

Select
     a.id
    ,a.datetime
    ,a.emp_id
    ,c.team_id
From 
    table_b as b
Left Join  
    table_a as a On a.id = b.id
Left Join 
    table_c On a.emp_id = c.emp_id
WHERE (a.datetime <> b.datetime OR b.datetime IS NULL);

更新解决方案的说明:没有什么可以考虑不匹配的行,因此连接中的 OR

请参阅下面有关联接的 Microsoft 文档。

https://docs.microsoft.com/en-us/sql/relational-databases/performance/joins?view=sql-server-ver15#:~:text=Joins%20indicate%20how%20SQL%20Server,be%20used%20for%20the%20join.

【讨论】:

  • 感谢 Eli,它完成了这项工作。现在要求已经改变,我需要删除匹配的记录(通过相同的 ID 和日期/时间)。有没有办法解决这个问题?
  • 很高兴。您是否需要简单地从表 A 中没有匹配记录的表 B 中选择所有?只是想确保我理解你的问题
  • 是的,这是正确的 Eli(你的解释比我好得多!)
  • 有趣 - 因为您没有从表 B 中选择任何字段。那么所有行都是空白的吗?如果您可以输入一些示例数据以及您期望的结果,那将是最好的。
  • 已添加示例数据,希望这会很清楚。我不希望“重复”行显示或显示空白
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-23
  • 1970-01-01
  • 2013-07-23
  • 2019-01-18
  • 1970-01-01
相关资源
最近更新 更多