【问题标题】:SQL query that returns all the ids without a certain value返回所有没有特定值的 id 的 SQL 查询
【发布时间】:2017-08-15 19:11:34
【问题描述】:

我有一个映射用户和功能的表。基本上为每个用户启用了哪些功能。该表是 |userId|featureId|具有一个(用户)对多(特征)的关系。

我想创建一个查询,该查询接受用户 ID 列表并返回缺少特定功能的用户 ID 列表。

意思是我需要确保每个 id 都有一个特定的 featureId。

userId  featureId
1       A
1       B
2       A
3       C
4       D
3       A

所以在本例中,我将获取 id 列表 (1, 2, 3, 4) 和 featureId A,查询将返回 userId 为 4 的一行,因为它是唯一启用了 feature A 的 userId。

【问题讨论】:

  • 所有功能的列表在哪里?理论上可能存在没有用户正确关联的功能?
  • 到目前为止你尝试过什么?发布您的查询。
  • 为什么不是用户 1 c,d 用户 2 b,c,d 用户 3 b,d 用户 4 a,b,c?我们怎么知道我们追求的是A?问题只是因为 4 个用户中有 3 个有 A 我们怎么知道那是我们想要的?

标签: mysql sql


【解决方案1】:

要查找没有功能 X 的用户列表,我将加入具有该功能的用户列表并返回不存在的用户。像这样:

SELECT *
FROM table_you_did_not_name as base
LEFT JOIN (
  SELECT DISTINCT userID
  FROM table_you_did_not_name
  WHERE feature = 'X'
) as sub ON base.userID = sub.userID
WHERE sub.userID is null

【讨论】:

    【解决方案2】:

    我想我可能已经回答了一个不同的问题:这并没有解决您的数据;但我不确定您如何确定您想要返回的是用户 4。因为每个用户都缺少其他用户的一些功能。也许我们只需要在下面为您的示例中的特定功能(A)添加一个 where 子句?

    从集合的角度考虑数据

    你需要

    1. 所有用户(用户或其他)的一组数据
    2. 所有特征(特征)的一组数据
    3. 以及用户具有哪些功能 (User_Feature)

    那么你需要

    1. 为每个用户生成一组每个功能(交叉连接)
    2. 识别用户已识别的那些。 (左加入 user_feature)
    3. 然后只保留那些没有发现特征的地方(user_feature 中没有记录)

    一种方法:这基本上是说为每个用户返回功能列表中存在但尚未与用户关联的功能。

    SELECT U.userID, F.FeatureID as FeatureIDMissing
    FROM USER U
    CROSS JOIN FEATURE F
    LEFT JOIN UserFeature UF
     on U.UserID = UF.UserID
    and F.FeatureID = UF.FeatureID
    WHERE UF.UserID is null
    --  and F.FeatureID = 'A' --maybe add this?
    

    替代方法:(结合两个步骤(2,3),只需排除用户已经存在的那些功能。

    这就是说,为每个用户返回未关联用户的所有功能

    SELECT U.userID, F.FeatureID as FeatureIDMissing
    FROM USER U
    CROSS JOIN FEATURE F
    WHERE not exists (SELECT *
                      FROM userFeature UF
                      WHERE U.UserID = UF.UserID
                        and F.FeatureID = UF.FeatureID)
    --and F.FeatureID = 'A' --maybe add this?
    

    任何一个答案都应该返回相同的结果。这是偏好数据库和性能的问题。查看执行计划以帮助确定最适合您和您的数据的方案。

    现在也许您的意思是您提供一个用户 ID 列表,您希望为所有这些用户生成一组独特的功能,然后返回没有这些功能的用户。如果是这样,您只需使用 (Select distinct FeatureID from userFeatures where UserID IN ('yourListHere') 而不是交叉加入功能,这将为这些用户生成一组独特的功能,并确定哪些用户缺少与该组用户共享的某些功能。

    所以...

    SELECT U.userID, F.FeatureID as FeatureIDMissing
    FROM USER U
    CROSS JOIN (SELECT distinct FeatureID 
                FROM userFeatures 
                WHERE UserID IN ('yourListHere')F
    LEFT JOIN UserFeature UF
     on U.UserID = UF.UserID
    and F.FeatureID = UF.FeatureID
    WHERE UF.UserID is null
    --  and F.FeatureID = 'A' --maybe add this?
    

    举个例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-29
      • 2022-11-17
      • 2021-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多