标识为实际记录创建多次的冲销记录

时间:2018-12-19 19:47:51

标签: sql oracle

我正在使用自定义界面将一些记录加载到项目的基表中。在此界面中,我需要为随后的month(Period)的实际记录创建冲销记录。由于某种原因,冲销记录被复制了,我可以看到为一个实际记录加载了多个冲销记录。 现在,我想确定为实际记录创建了多次的冲销记录。

例如:-我的表格数据如下所示

ID    Project   Emp No  Period  Hours    
--    -------   ------  ------  -----
 1     P1         E1    201810   10
 2     P1         E1    201811  -10
 3     P1         E1    201811  -10
 4     P1         E1    201811  -10

现在,我需要一个SQL查询来识别发生多次(在本例中,ID为3,4)的冲销记录。

查询输出如下所示

ID    Project   Emp No  Period  Hours    
--    -------   ------  ------  -----
 3     P1         E1    201811  -10
 4     P1         E1    201811  -10

任何人都可以帮我解决这个问题。

5 个答案:

答案 0 :(得分:1)

够了吗?

select t.*
from (select t.*
             row_number() over (partition by Project, EmpNo, Period, Hours order by id) as seqnum
      from t
     ) t
where seqnum >= 2;  

答案 1 :(得分:0)

获取不包含id每个不同组的最小值Project, EmpNo, Period, Hours的行:

SELECT t.* 
FROM tablename t
WHERE t.ID <> (
  SELECT MIN(tablename.ID) 
  FROM tablename 
  WHERE 
    tablename.Project = t.Project 
    AND 
    tablename.EmpNo = t.EmpNo 
    AND 
    tablename.Period = t.Period 
    AND 
    tablename.Hours = t.Hours
)

答案 2 :(得分:0)

grouping byhaving子句,在以下情况下显示所需结果

with tab( ID, Project, EmpNo, Period, Hours ) as
    (
     select 1,'P1','E1',201810, 10 from dual union all
     select 2,'P1','E1',201811,-10 from dual union all
     select 3,'P1','E1',201811,-10 from dual union all
     select 4,'P1','E1',201811,-10 from dual
    )  
select *
  from tab
 where ID > 
  ( select min(ID)
      from tab
    group by Project, EmpNo, Period, Hours
    having count(*) > 1
     );

    ID  PROJECT EMPNO   PERIOD  HOURS
    --  ------- ------  ------  -----
    3   P1      E1      201811   -10
    4   P1      E1      201811   -10

Rextester Demo

答案 3 :(得分:0)

这可以分为三个视图:(1)实际交易(2)多次冲销和(3)冲销明细

select dtl.* from 
  (select * from base_table where hours > 0) act,
  (select proj, emp, period, count(*), min(id) min_id 
   from base_table where hours < 0
   group by proj, emp, period having count(*) > 1) multi,
  (select * from base_table where hours < 0 ) dtl
where 
/* join actual transaction with multiple reversals.  NOTE: period clause below won't really handle year-month math */
act.emp = multi.emp
and act.proj = multi.proj
and to_number(act.period) + 1 = to_number(multi.period) 
/* find details of redundant reversals  */
and multi.min_id != dtl.id
and multi.emp = dtl.emp
and multi.proj = dtl.proj
and multi.period = dtl.period

也许不是最有效的解决方案,但应该可以工作(除非它需要处理201912实际需要的代码才能在201901中反转)

答案 4 :(得分:0)

在子查询中具有顺序和行数

select dt.ID,
       dt.Project,
       dt.Emp_No,
       dt.Period,
       dt.Hours from (    
select * from my_table order by Period desc) dt
where rownum <= 2