当每个字段有多个条目时,如何只返回一个字段?

时间:2018-05-01 18:28:27

标签: sql oracle pivot

我只想为每位员工返回一个电子邮件地址。员工既可以是员工,也可以是学生。如果您同时拥有员工和学生的电子邮件地址,那么我只想返回员工的电子邮件地址,如果您只有学生的电子邮件地址,则返回学生的电子邮件地址。

以下是整个查询:

select --spriden_pidm                                                as pidm,
    spriden_id                                                 as ban_id,
    spriden_last_name                                          as lastname, 
    spriden_first_name                                         as firstname,
    gmal.email,
    phone_number.area || phone_number.phone                    as phone_number,
    addr.permanent_address                                          AS street,
    addr.permanent_city                                             AS city,
    addr.permanent_state                                            AS state,
    addr.permanent_zip                                              AS zip,

case
    when nbrjobs_ecls_code in ('E1', 'E2', 'EN', 'F1', 'F2') and nbrjobs_ann_salary between 0 and 49999.99 then 'EHRA1'
    when nbrjobs_ecls_code in ('E1', 'E2', 'EN', 'F1', 'F2') and nbrjobs_ann_salary between 50000 and 99999.99 then 'EHRA2'
    when nbrjobs_ecls_code in ('E1', 'E2', 'EN', 'F1', 'F2') and nbrjobs_ann_salary between 100000 and 149999.99 then 'EHRA3'
    when nbrjobs_ecls_code in ('E1', 'E2', 'EN', 'F1', 'F2') and nbrjobs_ann_salary >= 150000 then 'EHRA4'
    when nbrjobs_ecls_code in ('SE', 'SN', 'LE') and nbrjobs_ann_salary between 0 and 49999.99 then 'SHRA1'
    when nbrjobs_ecls_code in ('SE', 'SN', 'LE') and nbrjobs_ann_salary between 50000 and 99999.99 then 'SHRA2'
    when nbrjobs_ecls_code in ('SE', 'SN', 'LE') and nbrjobs_ann_salary between 100000 and 149999.99 then 'SHRA3'
    when nbrjobs_ecls_code in ('SE', 'SN', 'LE') and nbrjobs_ann_salary >= 150000 then 'SHRA4'
    when nbrjobs_ecls_code in ('FA') then 'AF'
    when nbrjobs_ecls_code in ('SH', 'SS', 'TS', 'WS') then 'M1'
else 
    null
end as empl_cat
from nbrjobs a,
     spriden,
     (select goremal_pidm as pidm,
                goremal_email_address as email
        from goremal
        where goremal_emal_code in ('EMPL', 'STDN')
         and goremal_status_ind = 'A') gmal,
     (SELECT sprtele_pidm       AS pidm,
           sprtele_phone_area   AS area,
           sprtele_phone_number AS phone
      FROM sprtele c
     WHERE     sprtele_tele_code = 'CA'
           AND sprtele_primary_ind = 'Y'
           AND sprtele_status_ind IS NULL
           AND sprtele_seqno =
                   (SELECT MAX (sprtele_seqno)
                      FROM sprtele
                     WHERE     sprtele_tele_code = 'CA'
                           AND sprtele_primary_ind = 'Y'
                           AND sprtele_status_ind IS NULL
                           AND sprtele_pidm = c.sprtele_pidm)) phone_number,
     --spraddr
     (SELECT spraddr_pidm         AS pidm,
           spraddr_street_line1 AS permanent_address,
           spraddr_city         AS permanent_city,
           spraddr_stat_code    AS permanent_state,
           spraddr_zip          AS permanent_zip
      FROM spraddr b
     WHERE     spraddr_atyp_code = 'CA'
           AND spraddr_status_ind IS NULL
           AND spraddr_seqno =
                   (SELECT MAX (spraddr_seqno)
                      FROM spraddr
                     WHERE     spraddr_atyp_code = 'CA'
                           AND spraddr_status_ind IS NULL
                           AND spraddr_pidm = b.spraddr_pidm)) addr
where a.nbrjobs_pidm = spriden_pidm
 and a.nbrjobs_pidm = gmal.pidm(+)
 and a.nbrjobs_pidm = phone_number.pidm(+)
 and a.nbrjobs_pidm = addr.pidm(+)
 and spriden_change_ind is null
 and a.nbrjobs_sgrp_code = to_char(sysdate, 'YYYY') 
 and a.nbrjobs_effective_date = (select max(b.nbrjobs_effective_date) 
                                    from nbrjobs b
                                    where b.nbrjobs_pidm = a.nbrjobs_pidm
                                     and b.nbrjobs_posn = a.nbrjobs_posn
                                     and b.nbrjobs_effective_date <= sysdate
                                     --and b.nbrjobs_ecls_code in ('E1','E2','EN','F1','F2','SE','SN','LE')
                                     and b.nbrjobs_ecls_code in ('E1','E2','EN','F1','F2','SE','SN','LE', 'RF', 'AF', 'FA', 'SH', 'SS', 'TS', 'WS')
                                     and b.nbrjobs_sgrp_code = to_char(sysdate, 'YYYY'))                                    
 and a.nbrjobs_status <> 'T';`

这是我要更改的查询部分,以返回所需的电子邮件地址

(select goremal_pidm as pidm,
                goremal_email_address as email
        from goremal
        where goremal_emal_code in ('EMPL', 'STDN')
         and goremal_status_ind = 'A') gmal,

2 个答案:

答案 0 :(得分:0)

尝试使用NVL2,作为案例 -

NVL2(EMP_EMAIL_ADR,EMP_EMAIL_ADR,STDN_EMAIL_ADR)

如果Employee电子邮件地址不为null,则返回此子句,否则返回学生邮箱地址。

希望这有帮助。

答案 1 :(得分:0)

所以问题是,如果员工也是学生,查询将返回两个电子邮件地址?在这种情况下,您可以执行PIVOT数据,然后使用COALESCE()获取员工电子邮件为NULL的学生电子邮件。以下查询将替换有问题的子查询:

SELECT pidm, COALESCE(empl_email, stdn_email) AS email
  FROM (
    SELECT goremal_pidm AS pidm, goremal_email_address AS email, goremal_emal_code
      FROM goremal
     WHERE goremal_emal_code in ('EMPL', 'STDN')
       AND goremal_status_ind = 'A'
) PIVOT (
    MAX(email) FOR goremal_emal_code IN ('EMPL' AS empl_email, 'STDN' AS stdn_email)
)

编辑:另外,您可以使用条件聚合而不是显式PIVOT(如果您使用的是Oracle 9i或更低版本,则会很有帮助):

SELECT pidm, COALESCE(empl_email, stdn_email) AS email FROM (
    SELECT goremal_pidm AS pidm
         , MAX(CASE WHEN goremal_emal_code = 'EMPL' THEN goremal_email_address END) AS empl_email
         , MAX(CASE WHEN goremal_emal_code = 'STDN' THEN goremal_email_address END) AS stdn_email
      FROM goremal
     WHERE goremal_emal_code in ('EMPL', 'STDN')
       AND goremal_status_ind = 'A'
     GROUP BY goremal_pidm
)

希望这有帮助。