2011-10-11 61 views
1

我有類似下面的表格中顯示的另一個參數:SQL - 如果此參數存在顯示一排,否則,如果存在

ID |INFO  | DATE_DT 
------------------------- 
1091|info5 |10/10/2010 
1239|old.info |14/09/2010 
1340|old.info |07/10/2010 
3481|info  |16/10/2010 
4134|info3 |21/01/2011 

我想符合下列條件只顯示一行:
- 如果我在我的表中的一行與INFO = 'info' - >顯示只是此行
- 如果我沒有一行與INFO = 'info',所以我 - >與INFO = 'old.info'顯示行和DATE_DT = MAX(DATE_DT)

所以,在我的例子,如果我的桌子是:

ID |INFO  | DATE_DT 
------------------------- 
1091|info5 |10/10/2010 
1239|old.info |14/09/2010 
1340|old.info |07/10/2010 
3481|info  |16/10/2010 ===> display this row 
4134|info3 |21/01/2011 

,或者如果我的表犯規containt INFO = '信息'

ID |INFO  | DATE_DT 
------------------------- 
1091|info5 |10/10/2010 
1239|old.info |14/09/2010 
1340|old.info |07/10/2010 ===> display this row 
4134|info3 |21/01/2011 

有什麼建議?

謝謝。

回答

3

你可以選擇行和優先採取滿足第一條件之一:

SQL> WITH my_table AS (
    2 SELECT 1091 id, 'info5' info, to_date('10/10/2010') date_dt FROM DUAL 
    3 UNION ALL SELECT 1239, 'old.info' , to_date('14/09/2010') FROM DUAL 
    4 UNION ALL SELECT 1340, 'old.info' , to_date('07/10/2010') FROM DUAL 
    5 UNION ALL SELECT 3481, 'info'  , to_date('16/10/2010') FROM DUAL 
    6 UNION ALL SELECT 4134, 'info3' , to_date('21/01/2011') FROM DUAL) 
    7 SELECT * FROM (
    8  SELECT 1 ord, t.* 
    9  FROM my_table t 
10  WHERE info = 'info' 
11  UNION ALL 
12  SELECT 2 ord, t.* 
13  FROM my_table t 
14  WHERE date_dt = (SELECT MAX(date_dt) FROM my_table) 
15  ORDER BY ord) 
16 WHERE ROWNUM = 1; 

     ORD   ID INFO  DATE_DT 
---------- ---------- -------- ----------- 
     1  3481 info  16/10/2010 

如果刪除該行'info',其中DATE_DT = MAX(DATE_DT)將選擇行:

SQL> WITH my_table AS (
    2 SELECT 1091 id, 'info5' info, to_date('10/10/2010') date_dt FROM DUAL 
    3 UNION ALL SELECT 1239, 'old.info' , to_date('14/09/2010') FROM DUAL 
    4 UNION ALL SELECT 1340, 'old.info' , to_date('07/10/2010') FROM DUAL 
    5 /*UNION ALL SELECT 3481, 'info'  , to_date('16/10/2010') FROM DUAL*/ 
    6 UNION ALL SELECT 4134, 'info3' , to_date('21/01/2011') FROM DUAL) 
    7 SELECT * FROM (
    8  SELECT 1 ord, t.* 
    9  FROM my_table t 
10  WHERE info = 'info' 
11  UNION ALL 
12  SELECT 2 ord, t.* 
13  FROM my_table t 
14  WHERE date_dt = (SELECT MAX(date_dt) FROM my_table) 
15  ORDER BY ord) 
16 WHERE ROWNUM = 1; 

     ORD   ID INFO  DATE_DT 
---------- ---------- -------- ----------- 
     2  4134 info3 21/01/2011 
+0

優雅!謝謝 – mcha

2

你也可以用analytic functions來做到這一點,只需要一遍數據:

with my_tab as (
select 1091 as id, 'info5' as info, to_date('10/10/2010',' DD/MM/YYYY') as date_dt from dual 
union all select 1239, 'old.info', to_date('14/09/2010', 'DD/MM/YYYY') from dual 
union all select 1340, 'old.info', to_date('07/10/2010', 'DD/MM/YYYY') from dual 
union all select 3481, 'info', to_date('16/10/2010', 'DD/MM/YYYY') from dual 
union all select 4134, 'info3', to_date('21/01/2011', 'DD/MM/YYYY') from dual 
) 
select id, info, to_char(date_dt, 'DD/MM/YYYY') 
from (
    select id, info, date_dt, rank() over (order by ord, date_dt desc) as rnk 
    from (
     select id, info, date_dt, 
      case info 
       when 'info' then 1 
       when 'old.info' then 2 
       when 'info3' then 3 
       else null 
      end as ord 
     from my_tab 
    ) 
) 
where rnk = 1; 

     ID INFO  DATE_DT 
---------- -------- ---------- 
     3481 info  16/10/2010 

敲除「信息」行給出:

 ID INFO  DATE_DT 
---------- -------- ---------- 
     1340 old.info 07/10/2010 

恐怕沒有比@文森特更好地爲這個簡單例子,但更多的數據和更多的價值這之間做出選擇可能會變得更好 - 只是需要更多的ord值在這種情況下,儘管有任何真實的數據,但我曾想過你會從另一張表中查找優先順序...

+1

+1:我同意一般情況下,你的解決方案更好......但如果你有'date_dt'和'info'索引,我的解決方案只有幾個索引掃描:) –

+0

'更好'是如此主觀。 .. * 8-) –

相關問題