删除冗余数据

时间:2016-03-04 10:48:08

标签: sql oracle oracle10g

这是我的两张桌子

1)Salary_Details

SAL_NO                                    NOT NULL NUMBER
EMP_NO                                    NOT NULL VARCHAR2(10)
PAY_MONTH                                 NOT NULL DATE
RECORD_DATE                               NOT NULL DATE
CURRENT_BSAL                              NOT NULL NUMBER(10,2)
SAL_INCREMENT                             NOT NULL NUMBER(10,2)
FINAL_BSAL                                NOT NULL NUMBER(10,2)
DESCRIPTION                                        VARCHAR2(1000)

2)Pay_Details

PAY_NO                                    NOT NULL NUMBER
EMP_NO                                    NOT NULL VARCHAR2(10)
EMP_ERN_DDCT_NO                           NOT NULL VARCHAR2(20)
ERN_DDCT_CATNO                            NOT NULL VARCHAR2(10)
ERN_DDCT_CATNAME                          NOT NULL VARCHAR2(1000)
PAY_MONTH                                 NOT NULL DATE
AMOUNT                                    NOT NULL NUMBER(10,2)
EARN_DEDUCT                               NOT NULL CHAR(1)

这是我的oracle查询

select s.FINAL_BSAL,
       s.EMP_No,
       p.ERN_DDCT_CATNO,
       p.AMOUNT 
from salary_details s,
       pay_details p
where s.emp_no=p.emp_no 
and s.SAL_NO  IN (SELECT MAX(SAL_NO) 
                  FROM SALARY_DETAILS 
                  group by EMP_NO)

这是结果。(总共显示41行中的行数很少)

enter image description here

这里我需要删除Final_BSal和EMP_NO的复制数据。 我可以在EMP_NO或FINAL_BSAL上创建一个小组吗?如果是这样的话?

3 个答案:

答案 0 :(得分:1)

尝试以下查询

选择s.EMP_NO,        s.FINAL_BSAL,        listagg(p.ERN_DDCT_CATNO,',')WITHIN GROUP(ORDER BY p.ERN_DDCT_CATNO)ERN_DDCT_CATNO,        listagg(p.AMOUNT,',')WITHIN GROUP(ORDER BY p.AMOUNT)AMOUNT 来自salary_details s,pay_details p 其中s.emp_no = p.emp_no 和s.SAL_NO IN(EMP_NO从SALARY_DETAILS组中选择MAX(SAL_NO)) 按EMP_NO分组,FINAL_BSAL 按s.EMP_No排序

答案 1 :(得分:1)

您需要一个相关的子查询,而不是一个GROUP BY的子查询。另外,学习使用正确的显式JOIN语法。简单规则:从不FROM子句中使用逗号:

select s.FINAL_BSAL, s.EMP_No, p.ERN_DDCT_CATNO, p.AMOUNT
from salary_details s join
     pay_details p 
     on s.emp_no = p.emp_no
where s.SAL_NO = (SELECT MAX(SAL_NO)
                  FROM SALARY_DETAILS s2
                  WHERE s2.EMP_NO = s.EMP_NO
                 );

编写查询的一种更简单的方法是使用row_number()rank(),但以上只是对您的方法的简单修改。

答案 2 :(得分:1)

  

“我需要删除Final_BSal和EMP_NO的复制数据”

没有重复的数据。结果集中的每一行都是不同的。简单地说,您在SALARY_DETAILS中的每一行的PAY_DETAILS中都有多行。所以,有两个选择:

  1. 这是期望的结果,在这种情况下完成工作。
  2. 这不是理想的结果。如果是这样,您需要一个额外的业务规则,PAY_DETAILS上的过滤器,以确定要返回的单行。
  3. 例如,对WHERE子句的这一添加将仅返回上个月的PAY_DETAILS记录:

    and p.PAY_MONTH = trunc(add_months(sysdate, -1), 'MM')
    

    (假设PAY_MONTH在本月的第一天举行)。

    只有您(或您的用户)无法解释哪个是正确的,以及您可能需要应用哪些其他业务规则。