我有以下表格:
USER_GROUP
usergrp_id bigint Primary Key
usergrp_name text
用户
user_id bigint Primary Key
user_name text
user_usergrp_id bigint
user_loc_id bigint
user_usergrp_id
具有user_group表中的相应ID
user_loc_id
在分支表中有相应的id(branch_id)。
分支
branch_id bigint Primary Key
branch_name text
branch_type smallint
branch_type
默认设置为1.虽然它可以包含1到4之间的任何值。
user_projects
proj_id bigint Primary Key
proj_name text
proj_branch_id smallint
proj_branch_id
在分支表中有相应的id(branch_id)。
user_approval
appr_id bigint Primary Key
appr_prjt_id bigint
appr_status smallint
appr_approval_by bigint
appr_approval_by
具有来自用户表
的相应id(user_id)
appr_status
可能包含不同的状态值,例如单个appr_prjt_id
USER_GROUP
usergrp_id | usergrp_name
-------------------------
1 | Admin
2 | Manager
用户
user_id | user_name | user_usergrp_id |user_loc_id
---------------------------------------------------
1 | John | 1 | 1
2 | Harry | 2 | 1
分支
branch_id | branch_name | branch_type
-------------------------------------
1 | location1 | 2
2 | location2 | 1
3 | location3 | 4
4 | location4 | 2
5 | location4 | 2
user_projects
proj_id | proj_name | proj_branch_id
------------------------------------
1 | test1 | 1
2 | test2 | 2
3 | test3 | 1
4 | test4 | 3
5 | test5 | 1
6 | test5 | 4
user_approval
appr_id | appr_prjt_id | appr_status | appr_approval_by
-------------------------------------------------------
1 | 1 | 10 | 1
2 | 1 | 20 | 1
3 | 1 | 30 | 1
4 | 2 | 10 | 2
5 | 3 | 10 | 1
6 | 3 | 20 | 2
7 | 4 | 10 | 1
8 | 4 | 20 | 1
条件:每个MAX()
的输出必须取appr_status
appr_prjt_id
的{{1}}值并计算。
即,在上表appr_prjt_id=1
中有3种不同的状态:10,20,30。其数量只能显示在输出中对应于30的状态(不在状态10和20中),对应到特定branch_name
中的用户组。类似地,对于字段appr_prjt_id
期望输出:
10 | 20 | 30
------> Admin 0 | 1 | 1
|
location1
|
------> Manager 1 | 1 | 0
我该怎么做?
答案 0 :(得分:2)
select
branch_name, usergrp_name,
sum((appr_status = 10)::integer) "10",
sum((appr_status = 20)::integer) "20",
sum((appr_status = 30)::integer) "30"
from
(
select distinct on (appr_prjt_id)
appr_prjt_id, appr_approval_by, appr_status
from user_approval
order by 1, 3 desc
) ua
inner join
users u on ua.appr_approval_by = u.user_id
inner join
user_group ug on u.user_usergrp_id = ug.usergrp_id
inner join
branch b on u.user_loc_id = b.branch_id
group by branch_name, usergrp_name
order by usergrp_name
适用于大多数DBMS的经典解决方案是使用case
:
select
branch_name, usergrp_name,
sum(case appr_status when 10 then 1 else 0 end) "10",
但Postgresql具有布尔类型,它有一个转换为整数(boolean::integer
),结果为0或1,这样可以减少冗长的代码。
在这种情况下,也可以使用count
代替sum
:
select
branch_name, usergrp_name,
count(appr_status = 10 or null) "10",
我确实更喜欢count
,但我的印象是难以理解。诀窍是要知道count
计算任何不为空的东西,并且(true
或null)为true
且a(false
或null)为空,因此它将计数只要条件成立。