1

私は以下のデータを持っています

表1

id   col1    col2       col3
----------------------------------
1    abc   01/01/2012    -
1    abc   01/01/2012    A
2    abc   01/01/2012    -
2    abc   01/02/2012    -
3    abc   01/02/2012    -
3    xyz   01/01/2012    -
4    abc   01/02/2012    -
4    xyz   01/01/2012    -
4    xyz   01/02/2012    -

以下は評価するためです-

if(col1 is false) then evaluate col2 if(col2 is false) then col3:

Col1 - xyz has first preference from all values in this column
col2 - min date
col3 - not '-' or min(col3)

IDごとに1行だけを返したいのですが、col1が失敗した場合はcol2に移動し、失敗した場合はcol3条件に移動します。上記の表から、結果は次のようになります。

 id   col1    col2       col3
----------------------------------
 1    abc     01/01/2012  A
 2    abc     01/01/2012  -
 3    xyz     01/01/2012  -
 4    xyz     01/01/2012  -

密なランクを使ってみましたが、うまくいきませんでした。使用可能な関数またはSQLロジックを使用してこのロジックを実行する方法がわかりません。

for col1 - if more than one row for same code or xyz code then fail
for col2 - if more than one row with same min date then fail 
           [use this only if col1 condition fails]
4

2 に答える 2

8

分析関数で注文する多くの条件を指定できます

SELECT *
  FROM (SELECT id,
               col1,
               col2,
               col3,
               dense_rank() over (partition by id
                                      order by (case when col1 = 'xyz' 
                                                     then 1 
                                                     else 0 
                                                 end) desc,
                                               col2 asc,
                                               col3 asc) rnk
          FROM your_table)
 WHERE rnk = 1

あなたがタグdense_rankを使用したことを考えると、あなたが望むと思います。dense_rankネクタイをどのように処理したいか、またはネクタイが可能かどうかについては話しません。そのため、、、、または分析関数を使用するかどうかは、質問自体からは明確ではありrankませdense_rankrow_numberidごとに最高ランクの行のみをフェッチしていて、同じようrankdense_rank動作し、最初の場所に同点がある場合は複数の行を返す場合。 row_numberネクタイを任意に解除することにより、常に1行を返します。ごとに最初の行以外の行をフェッチする場合はid、タイについて考える必要があり、ととは異なる動作をrankdense_rankます。2つの行が最初に結び付けられている場合dense_rank、3番目の行にrnk2の場合、3rankのaが割り当てられrnkます。

これは、投稿したサンプルデータで機能するようです

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2  select 1 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  3  select 1 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, 'A' col3 from dual union all
  4  select 2 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  5  select 2 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  6  select 3 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  7  select 3 id, 'xyz' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  8  select 4 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  9  select 4 id, 'xyz' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
 10  select 4 id, 'xyz' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual
 11  )
 12  SELECT *
 13    FROM (SELECT id,
 14                 col1,
 15                 col2,
 16                 col3,
 17                 dense_rank() over (partition by id
 18                                        order by (case when col1 = 'xyz'
 19                                                       then 1
 20                                                       else 0
 21                                                   end) desc,
 22                                                 col2 asc,
 23                                                 col3 asc) rnk
 24            FROM x)
 25*  WHERE rnk = 1
SQL> /

        ID COL COL2      C        RNK
---------- --- --------- - ----------
         1 abc 01-JAN-12 A          1
         2 abc 01-JAN-12            1
         3 xyz 01-JAN-12            1
         4 xyz 01-JAN-12            1
于 2012-07-12T17:57:08.680 に答える
0
with tmp(id, col1, col2, col3, col1b, col3b) as
(select distinct id, col1, col2, col3,
        case when col1 = 'xyz' then '0' else '1' || col1 end,
        case when col3 = '-' then '1' else '0' || col3 end
from Table1)

select t1.id, t1.col1, t1.col2, t1.col3 
from tmp t1
left join tmp t2 on t1.id = t2.id
                and t1.col1b > t2.col1b
left join tmp t3 on t1.id = t3.id
                and t1.col1b = t3.col1b
                and t1.col2 > t3.col2
left join tmp t4 on t1.id = t4.id
                and t1.col1b = t4.col1b
                and t1.col2 = t4.col2
                and t1.col3b > t4.col3b
where t2.id is null
  and t3.id is null
  and t4.id is null
于 2012-07-12T18:40:09.567 に答える