需要找出一列的区别

时间:2019-06-28 09:28:56

标签: sql postgresql

我需要找到具有n的列的区别。通过第一阶段,第二阶段和最后阶段区分学生的学生人数。

例如,一列是学生,另一列是“阶段类型”。

   **Students**          **Phase Type**
   BALIPOGU SUNITHA        Phase 1
   GUDIPATI RAJESH         Phase 1
   GUDIPATI RAJESH         Phase 2
   KATUBOYINA YESWANTH     Phase 1
   VADITHYA RAHUL NAIK     Phase 1
   VADITHYA RAHUL NAIK     Phase 2
   VADITHYA RAHUL NAIK     Final
   BANDARU NANDIVARDHAN    Phase 1
   DODAGATTE SAI PREETHI   Phase 1
   G SHIRISHA G SHIRISHA   Phase 1
   KODASU OMKAR            Phase 1
   DUDEKULA KHAJA VALI     Phase 1 
   DUDEKULA KHAJA VALI     Phase 2
   DUDEKULA KHAJA VALI     Final
   RANGA SUDHA RANI        Phase 1
   RANGA SUDHA RANI        Phase 2

从上面的列表中,我需要检索第一阶段和第二阶段,第二阶段和期末学生的数据。

差异的计数。

第1阶段不存在的第2阶段学生名单和第2阶段不存在的最终学生名单以及总数。

预期输出:

   **diff of Phase 1 & Phase 2**         **Diff of Phase 2 & Final**
   BALIPOGU SUNITHA                          GUDIPATI RAJESH      
   KATUBOYINA YESWANTH                       RANGA SUDHA RANI
   BANDARU NANDIVARDHAN    
   DODAGATTE SAI PREETHI  
   G SHIRISHA G SHIRISHA   
   KODASU OMKAR           

2 个答案:

答案 0 :(得分:0)

insert into TEST values('raju','Phase 1')
insert into TEST values('ramu','Phase 2')
insert into TEST values('rajesh','Phase 1')
insert into TEST values('raghu','Phase 2')
insert into TEST values('rahul','Final')
insert into TEST values('sunny','Final')
insert into TEST values('kanna','Phase 1')
insert into TEST values('neeraj','Phase 2')
insert into TEST values('rajesh','Phase 2')
insert into TEST values('raghu','Phase 1')

--Nr of students per phase
SELECT PHASE_TYPE, COUNT(STUDENTS)
FROM TEST
GROUP BY PHASE_TYPE
ORDER BY PHASE_TYPE;

--Students in both Phase 1 and Phase 2
select t1.STUDENTS, concat(t1.phase_type,' and ', t2.phase_type) as PHASE 
from 
(SELECT STUDENTS, PHASE_TYPE
 FROM TEST
 WHERE
 PHASE_TYPE = 'Phase 1'
) t1
inner join 
(SELECT STUDENTS, PHASE_TYPE
FROM TEST 
WHERE
 PHASE_TYPE = 'Phase 2'
) t2
on t1.STUDENTS = t2.STUDENTS

答案 1 :(得分:0)

首先,对每个学生进行分类。您可以使用聚合来实现:

select student,
       (count(*) filter (where phase = 'Phase 1') > 0) as has_phase1,
       (count(*) filter (where phase = 'Phase 2') > 0) as has_phase2,
       (count(*) filter (where phase = 'Final') > 0) as has_final
from test
group by student;

那么最简单的方法是union all

with cte as (
      select student,
             (count(*) filter (where phase = 'Phase 1') > 0) as has_phase1,
             (count(*) filter (where phase = 'Phase 2') > 0) as has_phase2,
             (count(*) filter (where phase = 'Final') > 0) as has_final
      from test
      group by student
     )
select 'Phase 1 & Phase 2', student
from cte
where has_phase1 and has_phase2
union all
select 'Phase 2 & Final', student
from cte
where has_phase2 and has_final;

如果需要,可以将其分为两列:

with cte as (
      select student,
             (count(*) filter (where phase = 'Phase 1') > 0) as has_phase1,
             (count(*) filter (where phase = 'Phase 2') > 0) as has_phase2,
             (count(*) filter (where phase = 'Final') > 0) as has_final
      from test
      group by student
     )
select p12.student as phase_1_2,
       p2f.student as phase_2_f
from (select cte.*,
             row_number() over (order by student) as seqnum
      from cte
      where has_phase1 and has_phase2
     ) p12 full join
     (select cte.*,
             row_number() over (order by student) as seqnum
      from cte
      where has_phase2 and has_final
     ) p2f
     using (seqnum)
order by seqnum;