首页 > 解决方案 > 带有子表条件的sql计数基表

问题描述

user_table

|   uid  |
----------
|    1   |  
|    2   | 
|    3   | 
|    4   |    

用户角色表

|   uid       |   role      |  
-----------------------------  
|   1         |   Main1Role |  
|   1         |   Main2Role | 
|   1         |   Sub1Role  | 
|   1         |   Sub2Role  | 
|   2         |   Main1Role | 
|   2         |   Sub1Role  | 
|   3         |   Main1Role | 
|   3         |   Main2Role | 
|   4         |   Sub1Role  | 
|   4         |   Sub2Role  | 

如果用户具有主要角色,则不应将其计为子角色。

uid 1 计入 Main uid 2 计入 Main uid 3 计入 Main uid 4 计入 sub

就像给予主要用户更高优先级的用户总和

预期输出 MainRoleCount:3 SubRoleCount:1

标签: sqlpostgresql

解决方案


我不确定您的预期输出。

我明白了:你想获取每个角色的 uid 数量。但是,如果一个 uid 既是主角色又是子角色,则计数必须忽略子角色总数的 uid。

因此,在您的示例中,计数如下:

  • Main1Role 用于 uid 1、2、3:Count = 3
  • Main2Role 适用于 uids 1,3:Count = 2
  • Sub1Role是针对uids 1,2,4的,但是1和2有主要作用,所以只针对4:Count = 1
  • Sub2Role是针对1,4的,但是1有主要作用,所以只针对4:Count = 1

假设这是您想要的:

演示:db<>小提琴

SELECT
    role,
    SUM (
        CASE WHEN role IN ('Main1Role', 'Main2Role') THEN 1
             ELSE CASE WHEN ARRAY['Main1Role', 'Main2Role'] && array_agg THEN 0
                       ELSE 1 END
        END
    )
FROM (
SELECT
    *,
    array_agg(role) OVER (PARTITION BY uid)
FROM
    user_role_table
) s
GROUP BY role

增加预期输出。相同的想法,但子查询角色类型:

演示:db<>小提琴


推荐阅读