2011-10-11 65 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-) –

相关问题