sql查询以查找没有发布的应用程序的用户

w1e3prcc  于 2021-06-18  发布在  Mysql
关注(0)|答案(4)|浏览(422)

在我的数据库中,我有用户、应用程序和版本。用户可以通过权限表拥有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
            )
    );
egmofgnx

egmofgnx1#

你只需要使用 LEFT JOIN 在发布时,然后查找发布的应用程序数(r.app\u id为非空)为0的情况。如果你想要的只是一个用户列表,我认为你不需要 JOIN 这个 apps 一张table,就像 JOIN 正在打开 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
vlju58qv

vlju58qv2#

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

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将尝试连接多少行),很难判断此解决方案与以前发布的解决方案之间哪个更快。
有一件事很清楚,如果末尾没有“通过电子邮件分组”一行,您可能会看到用户的电子邮件在您的列表中重复多次。通常,有关sql的文献指出,在查询结束时使用“groupby”语句比在查询开始时使用“selectdistinct”语句更快地获得一个distinct集。

ippsafx7

ippsafx73#

第一个 Join 似乎是正确的 users 以及 permissions table。您只需检查加入的结果集中的app\u id是否存在于中 releases 不管是不是table。您可以尝试此查询-

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)
t40tm48m

t40tm48m4#

我会这样做,希望这有帮助:

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

相关问题