我有以下表格:
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可能包含不同的状态值,例如10,20,30 …对于单个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
条件:输出必须为每个appr_prjt_id获取appr_status的MAX()值并对其进行计数.
即,在上表中,appr_prjt_id = 1具有3种不同的状态:10,20,30.其计数必须仅显示在输出中对应于30的状态(不在状态10和20中),对应于用户组中的特定的branch_name.类似地,对于appr_prjt_id字段中的每个其他id
期望的输出:
10 | 20 | 30
------> Admin 0 | 1 | 1
|
location1
|
------> Manager 1 | 1 | 0
我怎样才能做到这一点?
最佳答案
SQL Fiddle
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的经典解决方案是使用案例:
select
branch_name, usergrp_name,
sum(case appr_status when 10 then 1 else 0 end) "10",
但Postgresql具有布尔类型,并且它具有转换为整数(布尔值::整数),从而产生0或1,这使得代码更简洁.
在这种情况下,也可以进行计数而不是总和:
select
branch_name, usergrp_name,
count(appr_status = 10 or null) "10",
我确实更喜欢伯爵,但我的印象是难以理解.诀窍是要知道count计算任何非null值并且a(true或null)为真且a(false或null)为null,因此只要条件为真,它就会计数.