db2中的复杂sql查询要求

时间:2016-09-02 10:22:30

标签: sql db2

我有一张表格如下:

   keyCol     |     date_O_Col      |    date_C_Col   |    statCol
--------------------------------------------------------------------
      1            2007-02-09          2012-11-02          C
      1            1990-01-31          <null>              O
      1            <null>              <null>              O
------------------------------------------------------------------------   

我想编写一个执行以下操作的查询:

1)比较两个日期列中的日期值,找出它们之间的最大日期。在上面的示例中,2012-11-02是两列中的最大日期。

2)由于2012-11-02位于date_C_Col,因此查询的结果行应为:

   keyCol     |     date_O_Col      |    date_C_Col   |    statCol
--------------------------------------------------------------------
      1             <null>               2012-11-02          C

即。使用相应的statCol发送最初属于该列的最大日期,并将其他日期列发送为空。

作为其他示例,表状态为:

       keyCol  |     date_O_Col      |    date_C_Col   |    statCol
--------------------------------------------------------------------
      2            2016-02-09               2016-03-09        C
      2            1990-01-31               2012-11-02        C
      2            2016-03-10               <null>            O
------------------------------------------------------------------------ 

应该导致:

       keyCol  |     date_O_Col      |    date_C_Col   |    statCol
--------------------------------------------------------------------
      2            2016-03-10               <null>            O

由于2016-03-10是最长日期,并且属于date_O_Col且对等statCol为O.

我正在使用db2 9。

4 个答案:

答案 0 :(得分:0)

您可以使用case

select t.keycol,
       (case when max(date_O_Col) is null and max(date_C_Col) is null then NULL
             when max(date_O_Col) is null then 'C'
             when max(date_C_Col) is null then 'O'
             when max(date_O_Col) > max(date_C_Col) then 'O'
             when max(date_C_Col) > max(date_O_Col) then 'C'
             else '='
        end)
from t
group by keycol;

我为您的问题未涵盖的边界情况编制了值:当值均为NULL或两者都相等时。

答案 1 :(得分:0)

您可以使用以下查询:

SELECT keyCol, 
       CASE WHEN date_O_Col = x.date_col THEN date_O_Col END,
       CASE WHEN date_C_Col = x.date_col THEN date_C_Col END,
       statCol
FROM mytable
CROSS JOIN (
   SELECT MAX(date_col) AS date_col
   FROM (SELECT CASE 
                   WHEN COALESCE([date_O_Col], '1900-01-01') > 
                        COALESCE([date_C_Col], '1900-01-01') 
                           THEN date_O_Col 
                   ELSE date_C_Col 
                END AS date_col
         FROM mytable) AS t) AS x
WHERE CASE 
         WHEN COALESCE([date_O_Col], '1900-01-01') > 
              COALESCE([date_C_Col], '1900-01-01') 
                 THEN date_O_Col 
         ELSE date_C_Col 
      END = x.date_col

Demo here

答案 2 :(得分:0)

根据我对您的其他帖子的回答finding-max-of-nullable-date-between-two-columns-in-db2 ...

如果多行具有相同的最大日期,则不会描述所需的结果。采取简单的假设,你想要所有行,然后以下将起作用。

select *
from mytable
where (select max(max(coalesce(date1,'00001-01-01')
                      ,coalesce(date2,'00001-01-01') 
                     )
                 )
         from mytable
      ) in (date1, date2)

答案 3 :(得分:0)

我不确定我是否完全理解这些要求,但是在查尔斯提供的查询的引导下,可能会进行以下设置和查询?:

设定:

create table so39290083 
( keyCol dec(1), date_O_Col date, date_C_Col date,  statCol char)
;
insert into  so39290083 values                                    
/*keyCol dec(1), date_O_Col date, date_C_Col date,  statCol char*/
  (   1   ,       '2007-02-09'  ,     '2012-11-02'    , 'C'  )    
, (   1   ,       '1990-01-31'  ,       null          , 'O'  )    
, (   1   ,        NULL         ,       null          , 'O'  )    
, (   2   ,       '2016-02-09'  ,     '2016-03-09'    , 'C'  )    
, (   2   ,       '1990-01-31'  ,     '2012-11-02'    , 'C'  )    
, (   2   ,       '2016-03-10'  ,       null          , 'O'  )    
;

查询:

select t.keycol                                                  
     ,  case t.statcol when 'O' then date_O_Col end as date_O_Col
     ,  case t.statcol when 'C' then date_C_Col end as date_C_Col
     , t.statcol                                                 
from so39290083 as T                                             
where ( t.keycol                                                 
      , case t.statcol when 'O' then date_O_Col                  
                       when 'C' then date_C_Col end ) in         
      ( select keycol                                            
             , max(max(coalesce( date_O_Col  , date'0001-01-01') 
                      ,coalesce( date_C_Col  , date'0001-01-01') 
                      ))                                         
        from so39290083 s                                        
        group by keycol                                          
      )                                                          
 ; -- likeness of a report from above query:
 KEYCOL  DATE_O_COL  DATE_C_COL  STATCOL
    1    -           2012-11-02     C   
    2    2016-03-10  -              O   
 ********  End of data  ********