2017-02-28 60 views
0

我有一个表EMPLOYEE为在其下是常见的删除特定数据:从表中基于某些字段

Enroll Date STS EMP_ID EMP_Name DEPT Rank OST BLOCK 
12-Jan-17 Q 123  ABC  ABC123 12 Y 1000  
14-Jan-17 Q 123  ABC  DEF123 12 Y 1000  
15-Jan-17 R 123  ABC  DEF123 12 Y 100 
15-Jan-17 R 123  ABC  DEF123 12 Y 200 
15-Jan-17 R 123  ABC  DEF123 12 Y 300 
20-Jan-17 R 123  ABC  DEF123 10 Y 300 
26-Jan-17 R 456  RST  DEF456 8 N 200 
26-Jan-17 R 456  RST  DEF456 8 N 300 
2-Feb-17  Q 123  ABC  ABC123 12 Y 300 

现在我需要删除对每个EMP_ID的重复行(重复如果EMP_NAME,DEPT,OST和排名相同)。如果2行有这4个值相同和enroll_date不同,那么我不需要删除该行。如果2行具有相同的登记日期并且4个字段(OST,EMP_Name,DEPT和等级)相同,那么我需要保留具有最高块的1000行(其次是300,然后是200,依此类推) 因此删除之后数据我的表应该有这些行:

Enroll Date STS EMP_ID EMP_Name DEPT Rank OST BLOCK 
12-Jan-17 Q 123  ABC  ABC123 12  Y 1000  
14-Jan-17 Q 123  ABC  DEF123 12  Y 1000  
15-Jan-17 R 123  ABC  DEF123 12  Y 100 
2-Feb-17  Q 123  ABC  ABC123 12  Y 300 
20-Jan-17 R 123  ABC  DEF123 10  Y 300 
26-Jan-17 R 456  RST  DEF456 8  N 200 
26-Jan-17 R 456  RST  DEF456 8  N 300 

我尝试使用下面的查询,并会删除已氡> 1

SELECT enroll_date,STS,BLOCK,EMP_ID,EMP_NAME,DEPT,RANK,OST行, row_number()over(分区BY emp_id,enroll_date,emp_name,dept,ost,rank ORDER BY enroll_date ASC,block DESC)FROM employee

但我每次只得到1。

有人可以检查这里的问题或建议一些其他方式来这样做吗?

+0

三行与15月都得到氡为1?这些日期值是否都是午夜时分 - 对于那些(或全部)行,'to_char(enroll_date,'SYYYY-MM-DD HH24:MI:SS')'显示时间还是oart?如果他们不是午夜的话,他们应该是吗? –

+0

请详细解释:“if ** 2 rows ** have .... then I need not delete ** that row **”。当你有两行时,哪一行是“那行”? – mathguy

+0

@ Mathguy- “如果2行的这4个值相同,并且enroll_date不同,那么我不需要删除那一行” 这意味着如果表中的任何2行具有完全相同的值(所有4列应具有相同的值)列OST,EMP_Name,DEPT和等级,那么需要删除行。但是在相同的情况下,如果对于OST,EMP_Name,DEPT和rank具有完全相同值的任何2行,enroll_date不同,那么我们需要保留两行。 – Mishti

回答

0

它看起来像你的enroll_date值有非午夜时间,所以划分这些也使得这些组合是独特的(即使他们只看到日期部分时看不到它)。

我最初的想法是,你的分析row_number()被太多列分隔了,而且你不应该包含你想要排序的日期值 - 它并没有真正意义上的分割和排序同样的事情,因为它是独一无二的。减少你真的想检查对列,也许是为了:

row_number() over (partition BY emp_id, emp_name, dept, ost, rank 
    ORDER BY enroll_date ASC, block DESC) 

会产生不同的等级,而不是全部为1,但我不认为这是正确的;这可能会使您的辅助块排序有点多余,因为对于一个ID,您可能不会有两行完全相同的时间。也许不太可能,但不是不可能的。

重新读你的措辞我不认为你想按enroll_date在所有的订购,而你想要日期而不是分区;但是,因为它包含您显然是想忽略这个练习非午夜时间,分区必须是对截断日期(头尾时间倒流到午夜,默认为:

row_number() over (partition BY trunc(enroll_date), emp_id, emp_name, dept, ost, rank 
    ORDER BY block DESC) 

随着您的样本数据作为CTE,包括每一天中不同的时间内,和一个额外的行把一切都相同的,但到目前为止,这说明你的原始rn和我的两个计算值:

with employee (enroll_date, sts, emp_id, emp_name, dept, rank, ost, block) as (
    select to_date('12-Jan-17 00:00:00', 'DD-Mon-RR HH24:MI:SS'), 'Q', 123, 'ABC', 'ABC123', 12, 'Y', 1000 from dual 
    union all select to_date('14-Jan-17 00:00:00', 'DD-Mon-RR HH24:MI:SS'), 'Q', 123, 'ABC', 'DEF123', 12, 'Y', 1000 from dual 
    union all select to_date('15-Jan-17 00:00:01', 'DD-Mon-RR HH24:MI:SS'), 'R', 123, 'ABC', 'DEF123', 12, 'Y', 100 from dual 
    union all select to_date('15-Jan-17 00:00:02', 'DD-Mon-RR HH24:MI:SS'), 'R', 123, 'ABC', 'DEF123', 12, 'Y', 200 from dual 
    union all select to_date('15-Jan-17 00:00:03', 'DD-Mon-RR HH24:MI:SS'), 'R', 123, 'ABC', 'DEF123', 12, 'Y', 300 from dual 
    union all select to_date('20-Jan-17 00:00:00', 'DD-Mon-RR HH24:MI:SS'), 'R', 123, 'ABC', 'DEF123', 10, 'Y', 300 from dual 
    union all select to_date('26-Jan-17 00:00:00', 'DD-Mon-RR HH24:MI:SS'), 'R', 456, 'RST', 'DEF456', 8, 'N', 200 from dual 
    union all select to_date('26-Jan-17 00:00:01', 'DD-Mon-RR HH24:MI:SS'), 'R', 456, 'RST', 'DEF456', 8, 'N', 300 from dual 
    union all select to_date('2-Feb-17 00:00:00', 'DD-Mon-RR HH24:MI:SS'), 'Q', 123, 'ABC', 'ABC123', 12, 'Y', 300 from dual 
    union all select to_date('3-Feb-17 00:00:00', 'DD-Mon-RR HH24:MI:SS'), 'Q', 123, 'ABC', 'ABC123', 12, 'Y', 300 from dual 
) 
SELECT to_char(enroll_date, 'DD-Mon-RR') as date_only, 
    enroll_date, sts, block, emp_id, emp_name, dept, rank, ost, 
    row_number() over (partition BY emp_id, enroll_date, emp_name, dept, ost, rank 
    ORDER BY enroll_date ASC, block DESC) your_rn, 
    row_number() over (partition BY emp_id, emp_name, dept, ost, rank 
    ORDER BY enroll_date ASC, block DESC) my_rn_1, 
    row_number() over (partition BY trunc(enroll_date), emp_id, emp_name, dept, ost, rank 
    ORDER BY block DESC) as my_rn_2 
FROM employee 
ORDER BY enroll_date; 

DATE_ONLY ENROLL_DATE   S BLOCK EMP_ID EMP DEPT RANK O YOUR_RN MY_RN_1 MY_RN_2 
--------- ------------------- - ----- ------ --- ------ ---- - ------- ------- ------- 
12-Jan-17 2017-01-12 00:00:00 Q 1000 123 ABC ABC123 12 Y  1  1  1 
14-Jan-17 2017-01-14 00:00:00 Q 1000 123 ABC DEF123 12 Y  1  1  1 
15-Jan-17 2017-01-15 00:00:01 R 100 123 ABC DEF123 12 Y  1  2  3 
15-Jan-17 2017-01-15 00:00:02 R 200 123 ABC DEF123 12 Y  1  3  2 
15-Jan-17 2017-01-15 00:00:03 R 300 123 ABC DEF123 12 Y  1  4  1 
20-Jan-17 2017-01-20 00:00:00 R 300 123 ABC DEF123 10 Y  1  1  1 
26-Jan-17 2017-01-26 00:00:00 R 200 456 RST DEF456 8 N  1  1  2 
26-Jan-17 2017-01-26 00:00:01 R 300 456 RST DEF456 8 N  1  2  1 
02-Feb-17 2017-02-02 00:00:00 Q 300 123 ABC ABC123 12 Y  1  2  1 
03-Feb-17 2017-02-03 00:00:00 Q 300 123 ABC ABC123 12 Y  1  3  1 

要确定的行删除你可以使用子查询:

SELECT enroll_date, sts, block, emp_id, emp_name, dept, rank, ost 
FROM (
    SELECT enroll_date, sts, block, emp_id, emp_name, dept, rank, ost, 
    row_number() over (partition BY trunc(enroll_date), emp_id, emp_name, dept, ost, rank 
     ORDER BY block DESC) as my_rn_2 
    FROM employee 
) 
WHERE my_rn_2 > 1 
ORDER BY enroll_date; 

ENROLL_DATE   S BLOCK EMP_ID EMP DEPT RANK O 
------------------- - ----- ------ --- ------ ---- - 
2017-01-15 00:00:01 R 100 123 ABC DEF123 12 Y 
2017-01-15 00:00:02 R 200 123 ABC DEF123 12 Y 
2017-01-26 00:00:00 R 200 456 RST DEF456 8 N 

虽然您需要决定实际上对您的数据和要求有意义的内容。

+0

我认为你是正确的,编辑查询并张贴与之相关的信息。它现在通过使用trunc函数更改enroll_date来工作。 – Mishti

+0

是否确定要在某一天使用具有最高块的行,即使是那一天有其他行的其他行也是如此?你忽略了时代 - 这可能实际上就是你想要的,但我会在删除任何东西之前检查它是否正确。不知道代表什么区块,这听起来有点奇怪。 –

0

我创建一个临时表,将所有非重复值:

create table employee_temp as 
with duplicates as (
SELECT enroll_date, STS, BLOCK, EMP_ID, EMP_NAME, DEPT,RANK, OST, row_number()  over (partition BY emp_id, trunc(enroll_date),emp_name, dept, ost, rank ORDER BY enroll_date ASC, block DESC)rn FROM employee) 
SELECT enroll_date, STS, BLOCK, EMP_ID, EMP_NAME, DEPT,RANK, OST from duplicates where rn =1; 
相关问题