如何根据在另一列中具有不同值的列从表中选择唯一记录

时间:2017-07-11 14:57:17

标签: sql oracle

我的SUBJ_SKILLS表下面有

之类的记录
TCHR_ID | LINE_NBR | SUBJ             | SUBJ_TYPE     
--------| -------  | ----------       | ---------- 
1       | 1        | Maths            | R
1       | 2        | 101              | U
2       | 1        | BehaviourialTech | U
3       | 2        | Maths            | R
4       | 1        | RegionalLANG     | U
5       | 3        | ForeignLANG      | U
5       | 4        | Maths            | R
6       | 2        | Science          | R
7       | 1        | 101              | U
7       | 3        | Physics          | R
..
..

我正在尝试检索下面的记录(即教授多个不同科目的单身教师)

TCHR_ID | LINE_NBR | SUBJ        | SUBJ_TYPE
--------| -------  | ----------  | ----------
5       | 3        | ForeignLANG | U
5       | 4        | Maths       | R
7       | 1        | 101         | U
7       | 3        | Physics     | R
1       | 1        | Maths       | R    
1       | 2        | 101         | U

这里,行号是唯一的,意味着TCHR_ID:5教授物理学(其中LINE_NBR = 1,但后来被删除)。因此,LINE_NBR不会更新并保持原样。

我还有一个查找表(SUBJ_LKUP)用于主题及其类别/类型如下(' R'用于常规主题和' U'用于唯一主题)

   SUBJ              | SUBJ_TYPE
  -----------------  | ------------
   Maths             | R
   Physics           | R
   ForeignLANG       | U
   101               | U
   Science           | R
   BehaviourialTech  | U
   RegionalLANG      | U 

我解决此问题的方法是创建一个表,其中包含2个教师记录,并在基表(SUBJ_SKILLS)和新表上使用另一个查询来过滤掉不同的记录。我提出了以下问题..

查询-1:

create table tchr_with_2_subj as select SS.TCHR_ID 
from SUBJ_SKILLS SS, SUBJ_LKUP SL 
where SS.SUBJ = SL.SUBJ
and SL.SUBJ_TYPE IN ('R', 'U') AND SS.TCHR_ID IN
    (select SS.TCHR_ID from SUBJ_SKILLS SS)
     GROUP BY SS.TCHR_ID HAVING COUNT(*) = 2)  

查询-2:

select SS.TCHR_ID from SUBJ_SKILLS SS, tchr_with_2_subj tw2s
where  SS.TCHR_ID = tw2s.TCHR_ID
GROUP BY SS.TCHR_ID,SS.SUBJ_TYPE HAVING COUNT(*) > 1)  

问题:

1)' IN' Query-1中的条件导致问题并拉错记录。

2)是否有更好的方法来编写查询以使用单个查询提取匹配记录(即,而不是创建表)

有人可以帮我这个。

3 个答案:

答案 0 :(得分:0)

对于原始问题的答案,我会使用窗口函数:

select ss.*
from (select ss.*,
             min(subj) over (partition by tchr_id) as mins,
             max(subj) over (partition by tchr_id) as maxs
      from SUBJ_SKILLS ss
     ) ss
where mins <> maxs;

目前还不清楚主题类型是如何适应的,但如果你需要包含它,那么类似的逻辑就可以了。

答案 1 :(得分:0)

您的第二张表可以从第一张表中获得:

select ss.*
from
    subj_skills as ss
    inner join (
        select tchr_id
        from subj_skills
        group by tchr_id
        having count(*) > 1
        ) as mult on mult.tchr_id=ss.tchr_id;

答案 2 :(得分:0)

我在这里使用分析函数,如:

select tchr_id, line_nbr, subj, SUBJ_TYPE
from (select count(distinct subj) over (partition by tchr_id) as grp_cnt,
             s.*
      from subj_skills s)
where grp_cnt > 1

如果您需要过滤掉无效记录,可以在内部查询中执行此操作。如果教师不能多次教授同一科目(请求多个不同的科目可以翻译成多个科目&#39;),那么我宁愿使用计数(*)而不是计数(不同的subj)。