2016-07-27 43 views
0

放棄與衝突的記錄行爲了更好地說明我的問題,我想出了一個示例場景如下所示:SQL:在一列

以下是客戶A和B的Open_Year銀行帳戶歷史記錄列表對於一些賬戶或者丟失或者與其他記錄衝突。

例如,帳戶A-3-UB表示具有兩個記錄列表中的一個帳戶,但是,它有兩個相互矛盾的Open_Year 1990 & 2012;帳戶A-1-BA有兩個記錄,其中一個記錄缺少Open_Year。

Customer Account_id Bank_id Open_Year Gender 
     A   1  BA  2000  F 
     A   1  BA   .  F 

     A   2  UB   .  F 

     A   3  UB  1990  F 
     A   3  UB  2012  F 

     A   4  UB  2013  F 
     A   4  UB  2013  . 

     A   5  UB   .  F 

     B   1  WF  2014  M 
     B   1  WF  2014  . 

     B   6  WF   .  . 

我想什麼有是通過一個單一的選擇查詢,有可能出現缺失/衝突的Open_Year這些帳戶將被丟棄完成,也就是說,返回的結果將是:

Customer Account_id Bank_id Open_Year Gender 
     A   4  UB  2013  F 
     A   4  UB  2013  . 
     B   1  WF  2014  M 
     B   1  WF  2014  . 

附加問題:

現在我們在最後添加了另一條記錄,並且我們還想在丟棄一行時創明鏡是相互矛盾或缺失至少一個值,同樣的要求作爲Open_Year:

Customer Account_id Bank_id Open_Year Gender 
     A   1  BA  2000  F 
     A   1  BA   .  F 

     A   2  UB   .  F 

     A   3  UB  1990  F 
     A   3  UB  2012  F 

     A   4  UB  2013  F 
     A   4  UB  2013  . 

     A   5  UB   .  F 

     B   1  WF  2014  M 
     B   1  WF  2014  . 

     B   6  WF   .  . 

     C   7  WB  2015  F 

預期結果將是:

Customer Account_id Bank_id Open_Year Gender 
     C   7  WB  2015  F 

回答

1

也可以通過具有這樣的使用羣體:

with a(Customer,Account_id,Bank_id,Open_Year,Gender) as (
select  'A'  , '1' , 'BA' , 2000,  'F' from dual union all 
select  'A'  , '1' , 'BA' , null , 'F' from dual union all 
select  'A'  , '2' , 'UB' , null , 'F' from dual union all 
select  'A'  , '3' , 'UB' , 1990 , 'F' from dual union all 
select  'A'  , '3' , 'UB' , 2012 , 'F' from dual union all 
select  'A'  , '4' , 'UB' , 2013 , 'F' from dual union all 
select  'A'  , '4' , 'UB' , 2013 ,  null from dual union all 
select  'A'  , '5' , 'UB' , null , 'F' from dual union all 
select  'B'  , '1' , 'WF' , 2014 , 'M' from dual union all 
select  'B'  , '1' , 'WF' , 2014 ,  null from dual union all 
select  'B'  , '6' , 'WF' , null ,  null from dual union all 
select  'C'  , '7' , 'AC' , 2016,  'F' from dual) 
select a.* 
    from a 
where (account_id, bank_id, Open_Year) in 
     (select account_id, bank_id , Open_Year 
      from a 
      group by account_id, bank_id , Open_Year 
     having count(*) > 1) 

    or customer in (select customer from a group by customer having count(*) = 1) 
+0

返回的錯誤說:子查詢不能選擇多個列。 –

+0

我在oracle 11g和10xe上測試了它(在10xe中需要一些帶鋸齒的修改),它的工作方式與預期一致。沒有關於子查詢的錯誤。 –

+0

我只是再次測試它,它對於示例數據集非常有效!還有一個問題:是否可以在單個查詢中同時過濾兩列(假設:Open_Year,Gender)? –

1

爲此,您可以使用窗口函數。這裏有一個方法:

select t.* 
from (select t.*, 
      count(distinct open_year) over (partition by account_id, bank_id) as cntd_oy, 
      count(*) over (partition by account_id, bank_id) as cnt, 
      count(open_year) over (partition by account_id, bank_id) as cnt_oy 
     from t 
    ) t 
where cntd_oy = 1 and cnt = cnt_oy 
+0

這工作得很好,戈登。謝謝!。 –

+0

@Ying。 。 。有沒有理由不接受這個答案?作爲OP,你可以接受你喜歡的任何答案,但我很好奇爲什麼。 –

+0

@Ying你需要三個計數器:全部,不爲零,並且不同。 – shawnt00