Sql 查询以仅获取某人的行
我有一张xx_wr表:Sql 查询以仅获取某人的行,sql,oracle,Sql,Oracle,我有一张xx_wr表: PERSON_NUM ACTION_CODE EFF_START_DATE EFF_END_DATE 10 RE 01-JAN-2016 31-DEC-4712 12 TERM 02-FEB-2016 01-MAR-2016 12 RE 02-MA
PERSON_NUM ACTION_CODE EFF_START_DATE EFF_END_DATE
10 RE 01-JAN-2016 31-DEC-4712
12 TERM 02-FEB-2016 01-MAR-2016
12 RE 02-MAR-2016 31-DEC-4712
理想情况下,当一个人有重复动作代码时,也应该有一个术语动作代码记录。例如:人数:12
我正在查询,以获取针对同一个人编号的所有人员,其中只有作为RE的操作代码,没有作为TERM的操作代码。例:10
SELECT *
FROM
( SELECT xx_WR.ACTION_CODE ACTION_CODE,
ROW_NUMBER() over (partition BY PERSON_NUM
ORDER BY ACTION_CODE) AS rn
FROM xx_WR ) T
WHERE RN =1
AND ACTION_CODE='RE';
此查询返回12和10。它应该只选择10,因为我们正在获取此表中操作代码为“RE”且没有“TERM”行的人号。如果您只需要具有单个
RE
操作代码的人号,请使用以下方法:
SELECT t1.*
FROM xx_wr t1
INNER JOIN
(
SELECT PERSON_NUM
FROM xx_wr
GROUP BY PERSON_NUM
HAVING COUNT(*) = 1
) t2
ON t1.PERSON_NUM = t2.PERSON_NUM
WHERE t1.ACTION_CODE = 'RE'
SELECT t1.*
FROM xx_wr t1
INNER JOIN
(
SELECT PERSON_NUM
FROM xx_wr
GROUP BY PERSON_NUM
HAVING SUM(CASE WHEN ACTION_CODE = 'TERM' THEN 1 ELSE 0 END) = 0 AND
SUM(CASE WHEN ACTION_CODE = 'RE' THEN 1 ELSE 0 END) > 0
) t2
ON t1.PERSON_NUM = t2.PERSON_NUM
如果您还可以接受具有多个操作代码的人员,只要术语
没有针对该人员出现,则使用以下方法:
SELECT t1.*
FROM xx_wr t1
INNER JOIN
(
SELECT PERSON_NUM
FROM xx_wr
GROUP BY PERSON_NUM
HAVING COUNT(*) = 1
) t2
ON t1.PERSON_NUM = t2.PERSON_NUM
WHERE t1.ACTION_CODE = 'RE'
SELECT t1.*
FROM xx_wr t1
INNER JOIN
(
SELECT PERSON_NUM
FROM xx_wr
GROUP BY PERSON_NUM
HAVING SUM(CASE WHEN ACTION_CODE = 'TERM' THEN 1 ELSE 0 END) = 0 AND
SUM(CASE WHEN ACTION_CODE = 'RE' THEN 1 ELSE 0 END) > 0
) t2
ON t1.PERSON_NUM = t2.PERSON_NUM
因此,ROW\u NUMBER()
仅此而已,它构建了一个行号。实际上,您需要比较每个人数的RE
记录数与TERM
记录数。根据您的描述,听起来您可能能够获得一个案例,例如RE->TERM->RE
,然后您也希望返回该案例。无论如何,这里使用窗口函数非常好,尤其是当您与条件聚合团队合作时。还请注意,此解决方案将处理RE->RE
案例,并且仍然返回最新的RE记录
注意:如果您只想找到完全没有学期记录的场景,您可以进行调整,例如:
SELECT *
FROM
(
SELECT
*
,ROW_NUMBER() OVER (PARTITION BY PERSON_NUM, ACTION_CODE ORDER BY EFF_END_DATE DESC) as rn
,COUNT(CASE WHEN ACTION_CODE = 'RE' THEN 1 END) OVER (PARTITION BY PERSON_NUM) as RECount
,COUNT(CASE WHEN ACTION_CODE = 'TERM' THEN 1 END) OVER (PARTITION BY PERSON_NUM) as TERMCount
FROM
xx_WR
) t
WHERE
t.rn = 1
AND t.ACTION_CODE = 'RE'
AND t.TERMCount = 0
如果您只希望某人有1个重新记录,而没有术语,您可以再次稍微更改where子句,或者您也不再需要行号,这样您就可以:
SELECT *
FROM
(
SELECT
*
,COUNT(CASE WHEN ACTION_CODE = 'RE' THEN 1 END) OVER (PARTITION BY PERSON_NUM) as RECount
,COUNT(CASE WHEN ACTION_CODE = 'TERM' THEN 1 END) OVER (PARTITION BY PERSON_NUM) as TERMCount
FROM
xx_WR
) t
WHERE
t.ACTION_CODE = 'RE'
AND t.RECount = 1
AND t.TERMCount = 0
查询以获取针对同一人号的所有人员,其中只有作为RE的操作代码,没有作为TERM的操作代码
如果我得到你的要求,你可以实现这个使用不存在也
SELECT *
FROM xx_WR a
WHERE a.ACTION_CODE='RE'
AND not exists ( select 1
from xx_WR b
where b.ACTION_CODE ='TERM'
and a.PERSON_NUM = b.PERSON_NUM)
您能否共享预期结果。内部查询使用此查询选择xx_WR.ACTION_code ACTION_code,COUNT(*)over(partition BY PERSON_NUM)AS rn FROM xx_WR