【问题标题】:SQL Server: getting data from second table when condition is matched wihtout duplicatesSQL Server:当条件匹配且不重复时从第二个表中获取数据
【发布时间】:2019-12-28 20:46:09
【问题描述】:

我有 2 个表(user、userContact),它们由 userID 列连接。

它们的结构有点像这样:

用户

[User_id]
[User_Name]

UserContact

[UserContact_id]
[User_id]
[UserContact_Type]
[UserContact_Description]

所以,对于同一个[User_id],可以有多个[UserContact_id]。

我的问题是:我想构建一个连接,它从表 User 中返回每个 [User_id],并在 [UserContact_Type] 等于 3 时包含 [UserContact_Description],但不要重复结果。

我尝试了什么:

SELECT DISTINCT 
    u.[User_id],
    CASE
       WHEN c.[UserContact_Type] = 3
          THEN c.[UserContact_Description]
    END AS UserContact
FROM 
    Table.user AS u
LEFT JOIN 
    Table.userContact AS c ON u.[User_id] = c.[User_id]

我得到这样的东西:

User_id    UserContact
----------------------
    6009    NULL
    7010    NULL
    7010    user7010@email.com
    7012    NULL
    8007    NULL
    8007    user8007@email.com

它返回来自Table.user 的每个结果,但它会复制与不同[UserContact_Type] 相关联的每个[User_id] 的数据,而不是3。

我需要的是仅在 [UserContact_Type] = 3 时返回 [UserContact_Description]

这是我在 StackOverflow 上的第一个问题。我希望我做得对,但请随时指出我在帖子中犯的任何错误。

非常感谢大家。

编辑:

正如您在下表中看到的,[User_id] 永远不会与同一个 [UserContact_Type] 相关

UserContact_id  User_id UserContact_Type
40107           4747        1
40108           4747        5
40109           4747        3
41107           5748        6
41108           5748        3
41215           6009        1
41216           6009        6
42222           7010        3
42223           7010        6
43214           8007        3

我想要什么:当我找到与 [UserContact_Type] = 3 相关的 [User_id] 时,返回它的 [UserContact_Description]。如果[User_id] 与条件无关,则不返回任何内容并将[UserContact_Description] 列留空或为空。

我要避免的结果是这样的:

User_id UserContact
    6009    NULL
    7010    NULL
    7010    user7010@email.com

[User_id] = 6009 没问题,但是 [User_id] = 7010 重复了,这是我的问题。我想要所有 [User_id]。但我只需要用 [UserContact_Type] 等于 3 来填充 UserContact 列。

希望现在更清楚。

【问题讨论】:

  • 那么那些NULL 行不应该在那里?
  • 我认为您只需要添加另一个加入条件。像LEFT JOIN Table.userContact as c ON u.[User_id] = c.[User_id] AND c.[UserContact_Type] = 3 假设您知道表中始终只有一条该类型的记录。
  • 另外,TABLEUSER 是 T-SQL 中的保留关键字,应避免用于对象名称和别名。如果这些是你的名字,那么你需要分隔标识。另外,您真的有一个名为[table] 的架构吗?这就像有一个名为[column] 的表:/
  • @Larnu 对 NULL 行没有问题。问题是重复的 [User_id] 行。不用担心,名称是虚构的,例如建议 =)
  • @ggon 您在 usercontact 表中的 (user_id, usercontact_type) 上有唯一的约束/索引吗?如果没有,那么您需要添加它或停止基于“如您所见......”的假设(并误导他人)。没有这个限制,你的假设最终会被发现并被证明是不正确的。

标签: sql sql-server join duplicates


【解决方案1】:

您需要表的左连接和条件聚合:

select u.[User_id], u.[User_Name],
  max(case 
      when c.[UserContact_Type] = 3 then c.[UserContact_Description] 
      else null 
    end 
  ) as UserContact_Description 
from [User] u left join [userContact] c
on c.[User_id] = u.[User_id]
group by u.[User_id], u.[User_Name]

请参阅demo

【讨论】:

  • 非常感谢!这个完成了这项工作。
【解决方案2】:

c.[UserContact_Type] = 3 条件移动到 ON 。如果只需要 [UserContact_Type] = 3,则省略 LEFT

SELECT DISTINCT u.[User_id],
                c.[UserContact_Description] as UserContact
    FROM [Table.user] AS u
    LEFT JOIN [Table.userContact] as c
      ON u.[User_id] = c.[User_id]
         AND c.[UserContact_Type] = 3

【讨论】:

  • 这只会给我带来与等于 3 的 [UserContact_Type] 相关的 [User_id]。但我需要表 [Table.user] 中的所有 [User_id] 并在 [UserContact_Description] 列中产生结果有一个与 [UserContact_Type] = 3 相关的 [User_id]。否则,[UserContact_Description] 列应为 NULL,但 [User_id] 绝不应重复。
  • LEFT JOIN 似乎是正确的答案。 @ggon 。也许您需要向我们提供一些示例数据和预期结果,以便我们了解为什么这种“主义不起作用”。
  • @ggon 所以你需要[UserContact_Type] 3 或NULL。是的,那你需要LEFT JOIN,不要省略。
【解决方案3】:

要跳过null 值,请尝试使用INNER JOIN

SELECT  u.User_id, c.UserContact_Description 
    FROM Table.user AS u

    INNER JOIN Table.userContact as c
      ON u.User_id = c.User_id
         AND c.UserContact_Type = 3

要获取与您的条件相关的所有值,请尝试使用LEFT JOIN

SELECT  u.User_id, c.UserContact_Description 
    FROM Table.user AS u

    LEFT JOIN Table.userContact as c
      ON u.User_id = c.User_id
         AND c.UserContact_Type = 3

【讨论】:

  • 与上述答案相同的问题。我对 [UserContact_Description] 列中的 NULL 结果没有任何问题。我只想带上 Table.user 中的每个 [User_id] 但避免重复。如果没有与 [UserContact_Type] = 3 相关的 [User_id],请给我 NULL,但不要为有的人复制 [User_id]。
  • 没有这样的事情,因为我要求仅在 [UserContact_Type] 等于 3 时才显示 [UserContact_Description]。并且每个 [User_id] 与多个 [UserContact_Type] = 3 没有相关性。但是它具有其他类型,这就是使 NULL 行重复结果的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-17
  • 2019-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多