2013-07-31 181 views
1

我有一個包含5列的表。第一列包含一個ID,兩列包含那些值爲0或1的ID的參數,第三列包含我需要作爲輸出的參數,最後一列包含日期。同一ID可在多個行具有不同的參數顯示:SQL:根據條件選擇唯一值

ID  parameter1  parameter2  parameter3  date 

001  0    1     A    01.01.2010 
001  0    1     B    02.01.2010 
001  1    0     C    01.01.2010 
001  1    1     D    01.01.2010 
002  0    1     A    01.01.2010 

對於每一個唯一的ID我想在parameter3返回值,從該行返回該值的決定是基於值parameter1parameter2和日期:

  • 如果有一行這兩個參數是0,我希望在這一行的值。
  • 如果沒有這樣的行,我想從該行的值,其中參數1是0和參數2是1
  • 如果沒有這樣的行,我想排在那裏參數1是1和參數2是0
  • 最後,如果沒有這樣的行,我想這兩行參數的值爲1

如果有多個行匹配所需的條件,我想要最近的日期的行。

例如,對於上面的表格,對於ID 001我希望第二行的參數3中的值爲B

什麼是最有效/最快速的方式來完成這個?我到目前爲止嘗試了兩種方法:

第一個是選擇所有不同的ID,然後使用帶where子句中的ID的select語句遍歷不同的ID,然後循環遍歷與ID匹配的所有行存儲在變量:必要的值

foreach 
    select distinct ID into i_ID from table1 
     foreach 
      let o_case = 5 
      select case 
       when parameter1 = 0 and parameter2 = 0 then 1 
       when parameter1 = 0 and parameter2 = 1 then 2 
       when parameter1 = 1 and parameter2 = 0 then 3 
       when parameter1 = 1 and parameter2 = 1 then 4 
       end, parameter3, date 
       into i_case, i_p3, i_date 
       from table3 
       where table3.ID = i_ID 

       if i_case < o_case 
        then let o_p3, o_case, o_date = i_p3, i_case, i_date; 
        else (if i_case = o_case and i_date > o_date 
         then let o_p3, o_date = i_p3, i_date; 
        end if; 
       end if; 
     end foreach; 
     insert into table_output values(i_ID; o_p3); 
end foreach; 

第二種方法是向左加入表本身四次的ID和上述的左加入如上所述應用參數1 &參數2的不同組合,然後通過嵌套nvl子句選擇輸出:

select ID, 
    nvl(t1.parameter3, 
     nvl(t2.parameter3, 
      nvl(t3.parameter3, 
       nvl(t4.parameter3)))) parameter3 
from table1 t0 
    left join table1 t1 
     on t0.ID = t1.ID and t1.parameter1 = 0 and t1.parameter2 = 0 
     and t1.date = (select max(date) from table1 t1a where t1a.ID = t1.ID)   
    left join table1 t2 
     on t0.ID = t2.ID and t2.parameter1 = 0 and t2.parameter2 = 1 
     and t2.date = (select max(date) from table1 t2a where t2a.ID = t1.ID) 
    left join table1 t3 
     on t0.ID = t3.ID and t3.parameter1 = 1 and t3.parameter2 = 0 
     and t3.date = (select max(date) from table1 t3a where t3a.ID = t3.ID) 
    left join table1 t4 
     on t0.ID = t4.ID and t4.parameter1 = 1 and t4.parameter2 = 1 
     and t4.date = (select max(date) from table1 t4a where t4a.ID = t4.ID) 

這兩種方法基本的工作,但是,由於該表是很長的,他們太緩慢。你會推薦什麼?

PS:DBMS是IBM的Informix 10,這不幸限制可用的功能的很多的範圍內。

+1

請你可以編輯你的文章,包括顯示你嘗試的兩個SQL查詢的代碼塊。另外,值得說明你正在使用的DBMS。 – w5m

回答

1

我不知道這是否是你想要的,但是這可能是工作:

SELECT id, parameter3 
FROM (
    SELECT id, parameter3, RANK() OVER (
      PARTITION BY id, parameter3 
      ORDER BY parameter1 ASC, parameter2 ASC, date DESC 
     ) 
    FROM tab 
) AS x 
WHERE x.rank = 1; 
+0

忘了提及我堅持使用IBM Informix 10.排名不在那裏工作,以及子句 –

+0

@MaxK對不起,聽到這些..我不能幫你.. –

0
ID  parameter1  parameter2  parameter3  date 

001  0    1     A    01.01.2010 
001  0    1     B    02.01.2010 

均具有相同的ID,paramaeter1,參數2,但不同的paraameter3上述行,它可以創建麻煩給你。

+0

我包括在內這是爲了證明表格的特徵。有些情況下,參數0和1中具有相同值的相同ID存在於多行中。但是,在這種情況下,日期會有所不同 –