SQL查询以查找具有未发布应用的用户

时间:2018-10-08 00:16:22

标签: mysql sql performance join exists

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

我正在尝试获取至少拥有1个应用程序的用户列表,但该用户的应用程序均未发布任何版本。

模式大致

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

认为我对此有一些帮助,但对我来说似乎效率很低,因为我两次提到了权限表,并且使用了嵌套的存在子句。有没有更有效的方式编写此查询?

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 个答案:

答案 0 :(得分:2)

第一个total = 0 def process_order(x_list): for x in len(x_list): print(f"You filled an order for{x[1]} {x[0]} for a total of {x[1]* x[2]}") x = [("oranges", 4, 3.22),("gummy bears",1,1.99),("sour bites", 3, 2.33), ("antacid", 1, 5.33)] while(len(x)>0): process_order(x) print("Total price: ${:.2f}".format(total)) Joinusers表之间似乎是正确的。您只需要检查permissions表中是否存在来自联接结果集中的app_id。您可以尝试此查询-

releases

答案 1 :(得分:2)

您只需要在发行版上使用LEFT JOIN,然后查找发行的应用程序数量(r.app_id为非NULL)为0的情况。如果您想要的只是一个用户列表,我认为您根本不需要JOIN apps表,因为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

答案 2 :(得分:1)

我会做这样的事情,希望对您有所帮助:

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

答案 3 :(得分:0)

您可以尝试的另一种方法是将左联接和内部联接结合起来,如下所示:

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的文献指出,在查询结束时使用“ group by”语句比在查询开始时使用“选择不同的”语句更快地获取唯一的集。