如何减去两个特定行并创建带有答案的自定义列
How to subtract two specific rows and create custom column with answer
我试图显示每个级别有多少用户与完成一个级别的总用户数。我需要唯一用户列是两列的减法,除了 Appr 级别我只需要它是用户列的重复,因为它是最高级别,
CPNT_ID
Users
Unique Users
Trainee
44662
11563 (which is 44662-33099)
SvcTech
33099
12420 (33099-20679)
CrewChief
20679
5079 (20679-15600)
SvcCoord
15600
6010 (15600-9590)
Appr
9590
9590 (this is the highest so no subtraction)
select
cpnt.cpnt_id
,count ( distinct pc.stud_id ) users
from
pa_stud_program sp,
pa_program p,
pa_student s,
pa_stud_cpnt pc,
ps_program_type pt,
pa_cpnt cpnt
WHERE p.PROGRAM_SYS_GUID = sp.PROGRAM_SYS_GUID
and pc.compl_dte is not null
and cpnt.cpnt_id in ('Trainee','SvcTech','CrewChief','SvcCoord','Appr')
and s.jp_id in ('1801','1805','1810','1811')
and s.EMP_STAT_ID = 'Active'
AND cpnt.CPNT_TYP_ID = p.CPNT_TYP_ID
AND cpnt.CPNT_ID = p.CPNT_ID
AND cpnt.REV_DTE = p.REV_DTE
AND pc.STUD_ID = sp.STUD_ID
AND sp.stud_id = s.STUD_ID
AND pc.CPNT_ID = sp.CPNT_ID
AND pc.CPNT_TYP_ID = sp.CPNT_TYP_ID
AND pc.REV_DTE = sp.REV_DTE
AND pc.seq_num = sp.seq_num
AND pt.PROGRAM_TYPE_ID = p.PROGRAM_TYPE
/** and s.PERSON_ID_EXTERNAL in [UserSearch]*/
group by cpnt.cpnt_id
order by users desc
看起来像是 lag
分析函数的候选对象。
SQL> with test as
2 -- sample data
3 (select 'Trainee' cpnt_id, 44662 users from dual union all
4 select 'SvcTech' , 33099 from dual union all
5 select 'CrewChief' , 20679 from dual union all
6 select 'SvcCoord' , 15600 from dual union all
7 select 'Appr' , 9590 from dual
8 )
9 -- subquery return "previous" CPNT_ID value which is then concatenated to its "pair"
10 -- joined on USERS value (as there's no other, at least not in your example)
11 select a.cpnt_id,
12 a.users,
13 a.cpnt_id || case when b.l_cpnt_id is not null then ' - '|| b.l_cpnt_id end
14 unique_users
15 from test a join (select cpnt_id,
16 users,
17 lag(cpnt_id) over (order by users) l_cpnt_id
18 from test
19 ) b on a.users = b.users
20 order by a.users desc;
CPNT_ID USERS UNIQUE_USERS
--------- ---------- ---------------------
Trainee 44662 Trainee - SvcTech
SvcTech 33099 SvcTech - CrewChief
CrewChief 20679 CrewChief - SvcCoord
SvcCoord 15600 SvcCoord - Appr
Appr 9590 Appr
SQL>
[编辑,更改要求后]
那就更简单了:
<snip>
11 select a.cpnt_id,
12 a.users,
13 a.users - nvl(b.l_users, 0) as unique_users
14 from test a join (select cpnt_id,
15 users,
16 lag(users) over (order by users) l_users
17 from test
18 ) b on a.users = b.users
19 order by a.users desc;
CPNT_ID USERS UNIQUE_USERS
--------- ---------- ------------
Trainee 44662 11563
SvcTech 33099 12420
CrewChief 20679 5079
SvcCoord 15600 6010
Appr 9590 9590
SQL>
将其实施到您的查询中:使用 CTE:
with your_query as
(select
cpnt.cpnt_id
,count ( distinct pc.stud_id ) users
from
pa_stud_program sp,
pa_program p,
pa_student s,
pa_stud_cpnt pc,
ps_program_type pt,
pa_cpnt cpnt
WHERE p.PROGRAM_SYS_GUID = sp.PROGRAM_SYS_GUID
and pc.compl_dte is not null
and cpnt.cpnt_id in ('Trainee','SvcTech','CrewChief','SvcCoord','Appr')
and s.jp_id in ('1801','1805','1810','1811')
and s.EMP_STAT_ID = 'Active'
AND cpnt.CPNT_TYP_ID = p.CPNT_TYP_ID
AND cpnt.CPNT_ID = p.CPNT_ID
AND cpnt.REV_DTE = p.REV_DTE
AND pc.STUD_ID = sp.STUD_ID
AND sp.stud_id = s.STUD_ID
AND pc.CPNT_ID = sp.CPNT_ID
AND pc.CPNT_TYP_ID = sp.CPNT_TYP_ID
AND pc.REV_DTE = sp.REV_DTE
AND pc.seq_num = sp.seq_num
AND pt.PROGRAM_TYPE_ID = p.PROGRAM_TYPE
group by cpnt.cpnt_id
)
select a.cpnt_id,
a.users,
a.users - nvl(b.l_users, 0) as unique_users
from your_query a join (select cpnt_id,
users,
lag(users) over (order by users) l_users
from your_query
) b on a.users = b.users
order by a.users desc;
我试图显示每个级别有多少用户与完成一个级别的总用户数。我需要唯一用户列是两列的减法,除了 Appr 级别我只需要它是用户列的重复,因为它是最高级别,
CPNT_ID | Users | Unique Users |
---|---|---|
Trainee | 44662 | 11563 (which is 44662-33099) |
SvcTech | 33099 | 12420 (33099-20679) |
CrewChief | 20679 | 5079 (20679-15600) |
SvcCoord | 15600 | 6010 (15600-9590) |
Appr | 9590 | 9590 (this is the highest so no subtraction) |
select
cpnt.cpnt_id
,count ( distinct pc.stud_id ) users
from
pa_stud_program sp,
pa_program p,
pa_student s,
pa_stud_cpnt pc,
ps_program_type pt,
pa_cpnt cpnt
WHERE p.PROGRAM_SYS_GUID = sp.PROGRAM_SYS_GUID
and pc.compl_dte is not null
and cpnt.cpnt_id in ('Trainee','SvcTech','CrewChief','SvcCoord','Appr')
and s.jp_id in ('1801','1805','1810','1811')
and s.EMP_STAT_ID = 'Active'
AND cpnt.CPNT_TYP_ID = p.CPNT_TYP_ID
AND cpnt.CPNT_ID = p.CPNT_ID
AND cpnt.REV_DTE = p.REV_DTE
AND pc.STUD_ID = sp.STUD_ID
AND sp.stud_id = s.STUD_ID
AND pc.CPNT_ID = sp.CPNT_ID
AND pc.CPNT_TYP_ID = sp.CPNT_TYP_ID
AND pc.REV_DTE = sp.REV_DTE
AND pc.seq_num = sp.seq_num
AND pt.PROGRAM_TYPE_ID = p.PROGRAM_TYPE
/** and s.PERSON_ID_EXTERNAL in [UserSearch]*/
group by cpnt.cpnt_id
order by users desc
看起来像是 lag
分析函数的候选对象。
SQL> with test as
2 -- sample data
3 (select 'Trainee' cpnt_id, 44662 users from dual union all
4 select 'SvcTech' , 33099 from dual union all
5 select 'CrewChief' , 20679 from dual union all
6 select 'SvcCoord' , 15600 from dual union all
7 select 'Appr' , 9590 from dual
8 )
9 -- subquery return "previous" CPNT_ID value which is then concatenated to its "pair"
10 -- joined on USERS value (as there's no other, at least not in your example)
11 select a.cpnt_id,
12 a.users,
13 a.cpnt_id || case when b.l_cpnt_id is not null then ' - '|| b.l_cpnt_id end
14 unique_users
15 from test a join (select cpnt_id,
16 users,
17 lag(cpnt_id) over (order by users) l_cpnt_id
18 from test
19 ) b on a.users = b.users
20 order by a.users desc;
CPNT_ID USERS UNIQUE_USERS
--------- ---------- ---------------------
Trainee 44662 Trainee - SvcTech
SvcTech 33099 SvcTech - CrewChief
CrewChief 20679 CrewChief - SvcCoord
SvcCoord 15600 SvcCoord - Appr
Appr 9590 Appr
SQL>
[编辑,更改要求后]
那就更简单了:
<snip>
11 select a.cpnt_id,
12 a.users,
13 a.users - nvl(b.l_users, 0) as unique_users
14 from test a join (select cpnt_id,
15 users,
16 lag(users) over (order by users) l_users
17 from test
18 ) b on a.users = b.users
19 order by a.users desc;
CPNT_ID USERS UNIQUE_USERS
--------- ---------- ------------
Trainee 44662 11563
SvcTech 33099 12420
CrewChief 20679 5079
SvcCoord 15600 6010
Appr 9590 9590
SQL>
将其实施到您的查询中:使用 CTE:
with your_query as
(select
cpnt.cpnt_id
,count ( distinct pc.stud_id ) users
from
pa_stud_program sp,
pa_program p,
pa_student s,
pa_stud_cpnt pc,
ps_program_type pt,
pa_cpnt cpnt
WHERE p.PROGRAM_SYS_GUID = sp.PROGRAM_SYS_GUID
and pc.compl_dte is not null
and cpnt.cpnt_id in ('Trainee','SvcTech','CrewChief','SvcCoord','Appr')
and s.jp_id in ('1801','1805','1810','1811')
and s.EMP_STAT_ID = 'Active'
AND cpnt.CPNT_TYP_ID = p.CPNT_TYP_ID
AND cpnt.CPNT_ID = p.CPNT_ID
AND cpnt.REV_DTE = p.REV_DTE
AND pc.STUD_ID = sp.STUD_ID
AND sp.stud_id = s.STUD_ID
AND pc.CPNT_ID = sp.CPNT_ID
AND pc.CPNT_TYP_ID = sp.CPNT_TYP_ID
AND pc.REV_DTE = sp.REV_DTE
AND pc.seq_num = sp.seq_num
AND pt.PROGRAM_TYPE_ID = p.PROGRAM_TYPE
group by cpnt.cpnt_id
)
select a.cpnt_id,
a.users,
a.users - nvl(b.l_users, 0) as unique_users
from your_query a join (select cpnt_id,
users,
lag(users) over (order by users) l_users
from your_query
) b on a.users = b.users
order by a.users desc;