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
我已经尝试了很多 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