代码之家  ›  专栏  ›  技术社区  ›  Jesse Shieh José Valim

SQL查询以查找应用程序未发布的用户

  •  2
  • Jesse Shieh José Valim  · 技术社区  · 6 年前

    在我的数据库中,我有用户、应用程序和版本。用户可以通过权限表拥有0..n个应用程序,而应用程序可以拥有0..n个版本。

    我正在尝试获取至少有一个应用程序的用户列表,但该用户的应用程序都没有任何版本。

    users  permissions  apps  releases
    -----  -----------  ----  --------
    id     user_id      id    id
    email  app_id             app_id
    

    认为 我有一些方法可以解决这个问题,但对我来说效率很低,因为我两次提到permissions表,并且使用嵌套exists子句。有没有更有效的方法来编写这个查询?

    select u.email from users u 
        join permissions p on p.user_id = u.id 
        where not exists (
            select a.id from apps a 
                join permissions p on p.app_id = a.id 
                where p.user_id = u.id and exists (
                    select r.id from releases r 
                        where r.app_id = a.id
                )
        ); 
    
    4 回复  |  直到 6 年前
        1
  •  2
  •   Nick    6 年前

    你只需要使用 LEFT JOIN 如果你只需要一个用户列表,我认为你不需要 JOIN 这个 apps 加入 permissions 将确保仅包括对1个或多个应用程序具有权限的用户。

    SELECT u.email
    FROM users u
    JOIN permissions p ON p.user_id = u.id
    LEFT JOIN releases r ON r.app_id = p.app_id
    GROUP BY u.email
    HAVING COUNT(r.app_id) = 0
    
        2
  •  2
  •   Vinit    6 年前

    第一个 Join 似乎是正确的 users permissions 桌子。您只需检查加入的结果集中的app\u id是否存在于中 releases

    select u.email from users u 
    join permissions p on p.user_id = u.id 
    where not exists ( Select 1 from releases r where r.App_id = p.app_id)
    
        3
  •  1
  •   Shidersz    6 年前

    SELECT
        u.id, u.email
    FROM
        users AS u
    INNER JOIN
        permissions AS p ON p.user_id = u.id
    LEFT JOIN
        releases AS r ON r.app_id = p.app_id
    GROUP BY
        u.id, u.email
    HAVING
        SUM(CASE WHEN r.id IS NOT NULL THEN 1 ELSE 0 END) = 0
    
        4
  •  0
  •   Leah H.A.    6 年前

    您可以尝试的另一种方法是左连接和内连接的组合,如下所示:

    Select
        email
    From users u
    Inner Join (
        Select
            p.user_id
            , p.app_id
         From permissions p
         Left Join releases r
            on p.app_id = r.app_id
         Where r.app_id is null) a
    on u.user_id = a.user_id
    Group by email
    

    有一件事很清楚,如果末尾没有“通过电子邮件分组”一行,您可能会看到用户的电子邮件在您的列表中重复多次。通常,有关SQL的文献指出,在查询结束时使用“groupby”语句比在查询开始时使用“selectdistinct”语句更快地获得一个distinct集。