2017-08-12 20 views
0

から重複レコードを取得できません: Tabel Structure私は下記の構造を持つテーブルがテーブル

A USER_IDは、特定の時間間隔で、それぞれの項目の値を持っています。項目値は、項目に応じてテキストまたは整数にすることができます。

2つ以上のUserIdが同じ値であるかどうかをチェックしたいと思います。つまり、アイテムが同じ値で同じ時間間隔で同じであることを意味します。

上記の表のように、UserId 213456とUserId 213458は同じレコードを持っています。 カーソルとループを使ってみましたが、時間がかかりすぎています。私のテーブルには5,000万人以上のユーザーIDがあります。効率的な方法でこれを行う方法はありますか?

サブクエリを使用してgroup byを使用しようとしましたが、すべての試みでそれに対して適切なクエリを作成できませんでした。

INTEGER_VALUE列を除くが、私の出力を与えていないとき、私はINTEGER_VALUE列が含まれている場合、私はHow do I find duplicate values in a table in Oracle?

select t1.USERID, count(t1.USERID) 
from USERS_ITEM_VAL t1 
where exists (select * 
       from USERS_ITEM_VAL t2 
       where t1.rowid <> t2.rowid and 
         t2.ITEMID = t1.ITEMID and 
         t2.TEXT_VALUE = t1.TEXT_VALUE and 
         --t2.INTEGER_VALUE = t1.INTEGER_VALUE and 
         t2.INIT_DATE = t1.INIT_DATE and 
         t2.FINAL_DATE = t1.FINAL_DATE) 
     group by t1.USERID having count(t1.USERID) > 1 order by count(t1.USERID); 

を使用して、次のクエリを作成している。しかし、問題はその作業で、参加けれどもINTEGER_VALUE欄で私のデータと同じ。これは自己結合を使用してアプローチする

USERID - NUMBER 
ITEMID - NUMBER 
TEXT_VALUE - VARCHAR2(500) 
INTEGER_VALUE - NUMBER 
INIT_DATE - DATE 
FINAL_DATE - DATE 
+0

https://stackoverflow.com/questions/59232/how-do-i-find-duplicate-values-in-a-table-in-oracle –

答えて

0

一つの方法: は、ここに私のテーブルの構造です。アイデアは、2人のユーザーが共通する項目の数をカウントすることです(日付列を考慮して)。

with t as (
     select t.*, count(*) over (partition by userid) as numitems 
     from t 
    ) 
select t1.userid, t2.userid 
from t t1 join 
    t t2 
    on t1.userid < t2.userid and 
     t1.itemid = t2.itemid and 
     t1.init_date = t2.init_date and 
     t1.final_date = t2.final_date and 
     t1.numitems = t2.numitems 
group by t1.userid, t2.userid, t1.numitems 
having count(*) = t1.numitems; 
+0

助けてくれてありがとうございました – John

0

あなたのクエリが失敗した理由がTEXT_VALUEかINTEGER_VALUEいずれかがすべての行にNULLになるということです。そして、それぞれが持っているアイテムの数にこれを比較します。このため、NVL関数を使用してNULL値をプラグインすることなく、自己結合で等価述語を使用することはできません。

Select * From (
Select t.*, Count(*) Over (Partition By t.itemId, 
             t.text_value, 
             t.integer_value, 
             t.init_date, 
             t.final_date) as Cnt) 
Where cnt > 1; 

クエリは、複数のレコードがPartition By句の5つの列で同じ値を持つすべての行を返す:

ただし、以下の目的を達成するために分析関数を使用するクエリです。

自己結合アプローチよりもこの手法の利点は、テーブルが1回だけスキャンされるのに対して、自己結合で2回スキャンされることです。これは、テーブルが大きい場合にパフォーマンスが向上する可能性があります。

関連する問題