【问题标题】:Check in T-SQL whether certain value sets exist in a related table在 T-SQL 中检查相关表中是否存在某些值集
【发布时间】:2022-11-23 06:59:50
【问题描述】:

我有下表:

用户 - 用户 ID、用户名、...

设置 - settingId, userId, settingKey, settingValue

例如对于 userId = 123,我可能有:

settingId: 1
userId: 123
settingKey: "allowClient"
settingValue: "0"

settingId: 2
userId: 123
settingKey: "allowAccess"
settingValue: "1"

那么例如,我如何查询所有用户的 settingValue 为“0”对应于“allowClient”的 settingKey 和 settingValue 为“1”对应于“allowAccess”的 settingKey?有时我正在寻找的 settingKey 和 settingValue 甚至可能不存在于特定用户,在这种情况下,我只想忽略这些用户。

我的“尝试”:

select * from User u inner join Settings s on u.userid = s.userid
where s.settingKey = 'allowClient and s.settingValue = '0'
and s.settingKey = 'allowAccess' and s.settingValue = '1'

由于明显的原因,这不起作用,因为它在所有条件上都加上了 AND。我不知道有任何 sql 结构可以解决这个问题,让我只说我真正想要的。

【问题讨论】:

  • 我确信这是一个相当普遍的事情,其中​​连接的结果集将包含多个记录。我不是 sql 专家,这就是我问这个的原因。
  • 我没有提供上面的示例数据吗?我不确定如何进一步简化它。
  • 引用第一条评论:带有示例数据,期望的结果和你的尝试.
  • 我的尝试?我在学校,需要展示我的作品吗?

标签: sql sql-server tsql


【解决方案1】:

您的第一次尝试不起作用,因为 WHERE 子句一次检查每一行。没有一行可以同时满足所有这些条件。

因此,您可以对两个键中的每一个使用 EXISTS() 检查,以非常直白地表达您的问题......

SELECT
  user.*
FROM
  user
WHERE
  EXISTS (
    SELECT *
      FROM settings
     WHERE userId = user.userId
       AND settingKey = 'allowClient'
       AND settingValue = '0'
  )
  AND
  EXISTS (
    SELECT *
      FROM settings
     WHERE userId = user.userId
       AND settingKey = 'allowAccess'
       AND settingValue = '1'
  )

根据数据特征,您可能受益于单个子查询而不是两个 EXISTS() 检查。

这更接近您尝试做的事情。

  • 过滤以获得每个用户两行(使用 OR 而不是 AND)
  • 聚合回单行并检查是否满足两个条件

(但我会先使用两个EXISTS(),让优化器完成它的工作。)

WITH
  matching_user
(
  SELECT
    userId
  FROM
    settings
  WHERE
    (settingKey = 'allowClient' AND settingValue = '0')
    OR
    (settingKey = 'allowAccess' AND settingValue = '1')
  GROUP BY
    userId
  HAVING
    COUNT(DISTINCT settingKey) = 2  -- DISTINCT only needed if one user has the same key set twice
)
SELECT
  user.*
FROM
  user
INNER JOIN
  matching_user
    ON user.userId = matching_user.userId

【讨论】:

    猜你喜欢
    • 2017-02-05
    • 2022-01-18
    • 2022-08-24
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多