SQL: Return 只有字段中有变化的行

SQL: Return only rows with changes in a field

我已经尝试了很多 google-fu,但无法完全找到我正在寻找的解决方案。大多数对于我的场景来说都太高级了。我也是SQL的新手,所以对于这个问题的新颖性,我深表歉意。

这是针对 Oracle 10g 的。

PS_JOB 员工拥有唯一的 EMPLID,但他们的 FILE_NBR 可以更改。我需要 return 每个有 FILE_NBR 变化的 EE 的 EMPLID。这是将 PS_JOB 与其他几个 table 连接起来的较大查询的一小部分,因此请具体说明解决方案应放在何处:在主 select 语句中,连接,或与其他 where 子句一起使用。

对于 PS_JOB

的简单 table 示例
EMPLID      FILE_NBR     Action    Date
0005         12345        Hire     01/01/2013
0005         67890        term     04/05/2015
0006         55555        Hire     02/05/2014
0006         55555        term     04/15/2015

我想要 return EMPLID 0005,因为它有一个 FILE_NBR 变化

添加编辑: 我想避免这样做,因为整个查询的目的有点不同。整个查询的目的是 return 具有 b.rehire_dt 值的 EE,在 a.ACTION_REASON 中没有 REH 值,并且 DID 具有 a.FILE_NBR 变化

Select a.paygroup, a.EMPLID, a.FILE_NBR, c.name, e.TLM_STATUS, b.rehire_dt  as "Emplmnt_Rltd_Dtes-Rehire Date",
CASE 
WHEN a.ACTION_REASON = 'REH' THEN 'Y'
ELSE 'N'
END -- confirms if EE is true rehire
FROM PS_EMPLOYMENT b --no effective dated rows

 right outer join SYSADM.PS_JOB a
 on a.emplid = b.emplid

  right outer join SYSADM.PS_PERSONAL_DATA c -- no effective dated rows
on a.emplid = c.emplid

  right outer join SYSADM.PS_SMS_SUBSCRB_TBL d
on a.paygroup = d.SUBSCRIBER_ID

  right outer join PORTAL.PS_TS_EMPL_TLM_STATUS e
 on a.emplid = e.emplid

  where

 b.rehire_dt IS NOT NULL
   --and a.EFFDT = (select max (a2.effdt) from SYSADM.PS_JOB a2 where     
  a.EMPLID = a2.EMPLID)
   and d.EFFDT = (select max (d2.effdt) from PS_SMS_SUBSCRB_TBL d2 where             
  d.SUBSCRIBER_ID = d2.SUBSCRIBER_ID)
  and e.EFFDT = (select max (e2.effdt) from PORTAL.PS_TS_EMPL_TLM_STATUS e2     
  where e.emplid = e2.EMPLID)
   and d.EFF_STATUS <> 'A'
--and a.action <> 'REH'
--and a.ACTION_REASON <> 'REH'
  --and b.rehire_dt = a.EFFDT 
  --and b.emplid = '50731/246'
  order by a.paygroup, a.emplid

感谢您的帮助!

亲切的问候, 克雷格

解决方案: 感谢@Adam_Martin 我几乎是从头开始,在 select 语句

中使用了 Adam 的案例代码
SELECT distinct JOB.EMPLID, JOB.PAYGROUP, PER.NAME, EMP.REHIRE_DT as "Empl_Rlated_Dates_Rehire_Date", SUB.EFF_STATUS as "Paygroup Status",TLM.TLM_STATUS,
CASE 
  WHEN JOB.ACTION_REASON = 'REH' THEN 'Y'
  ELSE 'N'
END as "True Rehire?", -- confirms if EE is true rehire

CASE -------------------------------Adam's code
  WHEN EXISTS(SELECT 1
            FROM PS_JOB otherJobs
           WHERE otherJobs.EMPLID = JOB.EMPLID
             AND otherJobs.FILE_NBR <> JOB.FILE_NBR) THEN 'Y'
ELSE 'N'
END as "Had FN Change?"

FROM SYSADM.PS_EMPLOYMENT EMP

 INNER JOIN SYSADM.PS_JOB JOB
   ON EMP.EMPLID = JOB.EMPLID

 INNER JOIN SYSADM.PS_PERSONAL_DATA PER -- no effective dated rows
  on JOB.emplid = PER.emplid

  INNER JOIN SYSADM.PS_SMS_SUBSCRB_TBL SUB
   on JOB.paygroup = SUB.SUBSCRIBER_ID

  INNER JOIN PORTAL.PS_TS_EMPL_TLM_STATUS TLM
   on JOB.emplid = TLM.emplid

WHERE
JOB.EMPLID = '50731/246'
and EMP.REHIRE_DT IS NOT NULL
and JOB.EFFDT = (select max (JOB2.effdt) from SYSADM.PS_JOB JOB2 where     
JOB.EMPLID = JOB2.EMPLID)
and SUB.EFFDT = (select max (SUB2.effdt) from PS_SMS_SUBSCRB_TBL SUB2 where   
SUB.SUBSCRIBER_ID = SUB2.SUBSCRIBER_ID and SUB2.EFF_STATUS = 'A')

一些评论;大多数人使用 LEFT JOIN 而不是 RIGHT,因为他们发现它们更容易阅读。养成这种习惯可能是个好习惯。此外,使用一致的间距样式,以便于阅读您正在做的事情。我在一侧对齐我的关键字,在另一侧对齐我的查询信息。

此查询将为您提供所有 EMPLID,其中至少有两个不同的 FILE_NBR

  SELECT PS_JOB.EMPLID
    FROM PS_JOB
GROUP BY PS_JOB.EMPLID
  HAVING MIN(PS_JOB.FILE_NBR) <> MAX(PS_JOB.FILE_NBR)

但是,我不确定您希望如何将它集成到您​​的查询中,这取决于您的需要。如果您只想 select 条目进行更改,则需要添加类似

的内容
AND EXISTS(SELECT 1
             FROM PS_JOB otherJobs
            WHERE otherJobs.EMPLID = a.EMPLID
              AND otherJobs.FILE_NBR <> a.FILE_NBR)

如果你只是想在你的 select 中使用它,你可以简单地将它存在于 case 语句中,表明你想要的存在。

例如:

CASE
  WHEN EXISTS(SELECT 1
                FROM PS_JOB otherJobs
               WHERE otherJobs.EMPLID = a.EMPLID
                 AND otherJobs.FILE_NBR <> a.FILE_NBR) THEN 'Y'
  ELSE 'N'
END