2016-10-13 25 views
0

特定のユーザー名から特定の条件に基づいて最良のレコードを選択できるようにするクエリを実行したいと思います。私は2つの列(col01、col02)を持っていますが、私が見ている基準です。一連の基準に基づいてレコードを選択する

•1つのレコード(下の例ではユーザー名a)に両方の列がある場合は、その列を優先してください。 1つのレコードは1つのレコードがcol01を持っている、とcol01がかかる以外は、はいとしてcol02を持って

•場合(下の例では、ユーザ名c)は、次の第二順位precenenceを取るはい、としてcol01を持って

•場合優先順位(下の例のユーザー名d)。

•あるレコードのcol02がyesで、他のレコードがnoの場合、列2より3番目の優先順位(下の例ではユーザー名g)が使用されます。

•両方のレコードは、これらのレコードが(ユーザ名のB、E、F)以下

さらに調査する必要があるとして返されるべきではないどちらよりも、同じである場合には、例えば、サンプルと出力されます。どのようにSQLクエリを使用して行うことができますか?

+----------+-----+-------+-------+ 
| username | id | col01 | col02 | 
+----------+-----+-------+-------+ 
| a  | 1 | yes | yes | 
| a  | 2 | yes | no | 
| b  | 3 | no  | no | 
| b  | 4 | no  | no | 
| c  | 5 | yes | no | 
| c  | 6 | no  | no | 
| d  | 7 | yes | no | 
| d  | 8 | no  | yes | 
| e  | 9 | no  | yes | 
| e  | 10 | no  | yes | 
| f  | 11 | yes | yes | 
| f  | 12 | yes | yes | 
| g  | 13 | no  | no | 
| g  | 14 | no  | yes | 
+----------+----+--------+-------+ 

出力

+----------+-----+-------+------+ 
| username | id | col01 | col02| 
+----------+-----+-------+------+ 
| a  | 1 | yes | yes | 
| c  | 5 | yes | no | 
| d  | 7 | yes | no | 
| g  | 14 | no  | yes | 
+----------+----+--------+------+ 

編集:私は状況を説明するよう求められました。基本的に、レコードは同じエリア(ユーザ名)から来ます。 col01は最新の情報で、col02は古いものです。両方の列が私たちにとって重要なので、両方がイエスであればそれが良い理由です。より最近のcol01は、より信頼できるデータがある場所です。すべてのレコードがまったく同じ場合は、データを理解するために少し深く掘り下げなければなりません。

+0

データサンプルの各レコードにメモを追加して、それが破棄された理由を説明することもできます。あなたの条件を理解することは難しいです。 – sagi

+0

ユーザ名 'f' –

+0

の場合、ユーザ名fは両方のレコードで同じ値を持つので、手動で調べなければなりません。 – user7002207

答えて

2

利用分析関数と、あなたが任意の必要はありません自己加入:

クエリ

SELECT username, 
     id, 
     col01, 
     col02 
FROM (
    SELECT t.*, 
     c.col2, 
     MIN(t.col01) OVER (PARTITION BY username) AS mincol01, 
     MAX(t.col01) OVER (PARTITION BY username) AS maxcol01, 
     MIN(c.col02) OVER (PARTITION BY username) AS mincol02, 
     MAX(c.col02) OVER (PARTITION BY username) AS maxcol02, 
     ROW_NUMBER() OVER (PARTITION BY username 
          ORDER BY t.col01 DESC, c.col02 DESC) AS rn 
    FROM table_name t 
     INNER JOIN 
     col02_table c 
     ON (t.id = c.id) 
) 
WHERE (mincol01 < maxcol01 OR mincol02 < maxcol02) 
AND rn = 1; 

出力

USERNAME ID COL01 COL02 
-------- -- ----- ----- 
a   1 yes yes 
c   5 yes no 
d   7 yes no 
g  14 no yes 
+0

こんにちは、これを修正できるかどうか聞いてみました。私は間違いを犯し、col02が別のテーブルにあることに言及するのを忘れてしまった。ありがとうございました。 – user7002207

+0

@ user7002207更新 - 2つのテーブルに対して内部結合を使用するだけです。 – MT0

+0

ありがとうございました – user7002207

0

yesのレコードとcol01 = yesのレコードのみ、col02 = yesのレコードのみ、複数の外部自己結合を使用します。次に、idがそのセット内の最初のレコードのIDであるレコードを選択するだけです(同名の行のIDはyes、同じ名前の行のIDはcol01 = yesなどです)
dupesである行を取り除くには、username、col01、およびcol02に同じ値を持つ別の行(別のidを持つ)がある行を除外します。

Select distinct a.username, a.id, 
    a.col01, a.col02 
From table a 
    left join table b -- <- this is rows with both cols = yes 
     on b.username=a.username 
      and b.col01='yes' 
      and b.col02='yes' 
    left join table c1 -- <- this is rows with col1 = yes 
     on c1.username=a.username 
      and c1.col01='yes' 
      and c1.col02='no' 
    left join table c2 -- <- this is rows with col2 = yes   
     on c2.username=a.username 
      and c2.col01='no' 
      and c2.col02='yes' 
Where a.id = coalesce(b.id, c1.Id, c2.Id) 
    and not exists -- <- This gets rid of f 
     (select * from table 
     where username = a.username 
      and id != a.id 
      and col01 = a.col01 
      and col02 = a.col02) 

col02は別のテーブルにある場合、その後、あなたがテーブルを使用してcol02を必要とする各場所で、あなたは別の、この他のテーブルへの結合追加する必要があります。

Select distinct a.username, a.id, 
    a.col01, ot.col02 
From (table a join other table ot 
      on ot.id = a.Id) 
    left join (table b join otherTable ob -- <- this rows with both cols yes 
        on ob.id= b.id) 
     on b.username=a.username 
      and b.col01='yes' 
      and ob.col02='yes' 
    left join (table c1 join otherTable oc1 -- <- this rows with col1 yes 
        on oc1.id= c1.id) 
     on c1.username=a.username 
      and c1.col01='yes' 
      and oc1.col02='no' 
    left join (table c2 join otherTable oc2 -- <- this rows with col2 yes 
        on oc2.id= c2.id)   
     on c2.username=a.username 
      and c2.col01='no' 
      and oc2.col02='yes' 
Where a.id = coalesce(b.id, c1.Id, c2.Id) 
    and not exists -- <- This gets rid of f 
     (select * from table e 
      join otherTable oe 
       on oe.id= e.id 
     where e.username = a.username 
      and e.id != a.id 
      and e.col01 = a.col01 
      and oe.col02 = a.col02) 
+0

私は間違いをしました。 col02は別のテーブルにあります。何とかこのコードを組み込むことはできますか? – user7002207

+0

はい、2つのテーブルを結合する必要があります。私は2つのテーブルの関係を知らないと助けにならない。 –

+0

idフィールドを使用して結合できます。 idmのようなものになる – user7002207

1
with 
    inputs (username, id, col01 , col02) as (
     select 'a', 1, 'yes', 'yes' from dual union all 
     select 'a', 2, 'yes', 'no' from dual union all 
     select 'b', 3, 'no' , 'no' from dual union all 
     select 'b', 4, 'no' , 'no' from dual union all 
     select 'c', 5, 'yes', 'no' from dual union all 
     select 'c', 6, 'no' , 'no' from dual union all 
     select 'd', 7, 'yes', 'no' from dual union all 
     select 'd', 8, 'no' , 'yes' from dual union all 
     select 'e', 9, 'no' , 'yes' from dual union all 
     select 'e', 10, 'no' , 'yes' from dual union all 
     select 'f', 11, 'yes', 'yes' from dual union all 
     select 'f', 12, 'yes', 'yes' from dual union all 
     select 'g', 13, 'no' , 'no' from dual union all 
     select 'g', 14, 'no' , 'yes' from dual 
    ) 
-- Query begins here 
select username, 
     max(id) keep (dense_rank last order by col01, col02) as id, 
     max(col01)           as col01, 
     max(col02) keep (dense_rank last order by col01)  as col02 
from  inputs 
group by username 
having min(col01) != max(col01) or min(col02) != max(col02) 
; 



USERNAME ID COL COL 
-------- --- --- --- 
a   1 yes yes 
c   5 yes no 
d   7 yes no 
g   14 no yes 
+0

私たちは見るべき約4500のユーザー名を持っているのでこれがうまくいくかどうかは分かりません。でもありがとう。 – user7002207

+0

なぜですか?クエリは5人のユーザーまたは50万人で動作しますが、なぜそうは思わないでしょうか? – mathguy

+0

私はSQLで熟達していないと言ってこれを序文にしたいので、私が何を話しているのか分からないかもしれません。私は手動で入力する必要があるという仮定の下にありました。 "--query begins here"というデータはすべて実行可能ではありません。私が誤解した場合はお詫び申し上げます。上部のデータは手動で入力する必要がありますか? – user7002207

関連する問題