【问题标题】:SQL Query to count users with left join of 2 tablesSQL 查询以计算具有 2 个表的左连接的用户
【发布时间】:2017-08-17 05:36:29
【问题描述】:

我正在尝试计算在我们的 2 个应用程序中的 1 个应用程序中处于非活动状态的用户数。

我有 2 个表 - Users 表和 User_Applications 表,其中的行包含用户 ID、应用程序 ID 和布尔值(无论它们是否处于活动状态)。

如果用户已获得对应用程序的访问权限,则会在 User_Applications 中添加一行。因此,如果他们已获得对 App A 和 App B 的访问权限,则有 2 行。如果他们只被授予对应用 A 的访问权限,则只有 1 行。

假设如果User_Applications中没有关于App B的记录,那么用户是不活跃的。如果 User_Applications 中的用户根本不存在任何记录,则它们在 App A 和 App B 中均处于非活动状态。

想象一下这样的连接:

| user_id | app_id | active |  
|---------|--------|--------|  
| 1       | 'A'    | false  |  
| 1       | 'B'    | true   |  
| 2       | null   | null   |  
| 3       | 'B'    | true   |

如果我计算 A 中处于非活动状态的用户数,则用户 1、2 和 3 都处于非活动状态。但是,我的 SQL 脚本只计算像 1 和 2 这样的用户。它不计算像 3 这样的用户。如何在我的查询中包括像 #3 这样的用户?

我编写了这个 SQL 脚本来统计 App A 中的非活动用户数:

SELECT COUNT(*) FROM Users u
LEFT JOIN User_Applications s on u.user_id = s.user_id
WHERE (s.app_id = 'A' OR s.app_id IS NULL)
AND (s.active = false OR s.active IS NULL);

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    下面的代码是你要找的吗?

    SELECT COUNT(*) FROM Users u
    LEFT JOIN User_Applications s on u.user_id = s.user_id
    WHERE (s.app_id = 'A' OR s.app_id = 'B' OR s.app_id IS NULL) AND (s.active = false OR s.active IS NULL);
    

    【讨论】:

      【解决方案2】:

      只需使用条件COUNT(),而是尝试计算每个用户有多少活跃应用。然后你计算谁没有 2 个活跃的应用程序

      SELECT COUNT(*)
      FROM (
          SELECT COUNT(CASE WHEN s.active THEN 1 ELSE NULL END) 
          FROM Users u
          LEFT JOIN User_Applications s 
            ON u.user_id = s.user_id
          GROUP BY user_id
          HAVING COUNT(CASE WHEN s.active THEN 1 END) < 2
      ) T
      

      我添加了ELSE NULL,但它是ELSE的默认值,所以如果你不添加它也可以工作

      COUNT() 不算为空。因此,如果用户没有应用程序的权限,left join 返回null 并且不会计数,如果用户不活跃,CASE 也将返回 null 并且不会计数

      所以你会发现那些没有 2 个活跃应用的人。

      【讨论】:

        【解决方案3】:

        从 ('A' , 'B') 列表中统计拥有最多 1 个活动应用的用户

        SELECT COUNT(*) FROM Users u
        LEFT JOIN ( 
           SELECT user_id, COUNT(*) nActive
           FROM User_Applications 
           WHERE app_id IN ('A' , 'B') AND active
           GROUP BY user_id 
        ) s on u.user_id = s.user_id
        WHERE (s.nActive <= 1 OR s.nActive IS NULL)
        
        猜你喜欢
        • 2020-12-15
        • 1970-01-01
        • 1970-01-01
        • 2015-02-05
        • 2019-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-16
        相关资源
        最近更新 更多