Oracle SQL比较要列出的日期

时间:2014-12-12 16:51:50

标签: sql oracle date

我有一个模型,序列,日期列表(数据库中不存在日期)。我需要在提供给我的日期之前提取模型,序列号和最近的通话日期。我确实找到了一个使用CASE工作的“解决方案”但是想知道是否有更简单的方法。当有一个100多个项目的列表时,OR CASE语句有点麻烦可以使用。

SELECT   M.MODEL_NBR, DEV.SERIAL, i.c_date 
  FROM   device dev, 
         model m, 
         A_DEVICE ad, 
         INTR i 
 WHERE   (DEV.SERIAL, i.intr_id) IN 
            (select serial, max(t.intr_id) over (partition by t.part_id)
               from intr t, device d
              where t.part_id = AD.PART_ID 
                and d.device_id = ad.device_id
                and d.model_type = 'XX'
                and d.serial in ('1234', '5678')
                and (1 = (case 
                          when d.serial = '1234'
                           and t.c_date < to_date('10/10/2014', 'mm/dd/yyyy')
                          then 1
                           end)
                  or 1 = (case 
                          when d.serial = '5678'
                           and t.c_date < to_date('11/11/2014', 'mm/dd/yyyy')
                          then 1
                           end)))
         AND M.MODEL_ID = DEV.MODEL_ID 
         and M.MODEL_NBR = '1111' 
         AND DEV.DEVICE_ID = AD.DEVICE_ID 
         AND AD.PART_ID = I.PART_ID 
         order by DEV.SERIAL;

1 个答案:

答案 0 :(得分:1)

CASE子句中的WHERE几乎总是更好地表示为AND/OR表达式。在这种情况下,而不是:

and d.serial in ('1234', '5678')
and (1 = (case 
           when d.serial = '1234'
                and t.c_date < to_date('10/10/2014', 'mm/dd/yyyy')
           then 1
           end)
      or 1 = (case 
              when d.serial = '5678'
                   and t.c_date < to_date('11/11/2014', 'mm/dd/yyyy')
              then 1
              end)))

你最好使用:

and ((   d.serial = '1234'
         and t.c_date < to_date('10/10/2014', 'mm/dd/yyyy'))
     or (d.serial = '5678'
         and t.c_date < to_date('11/11/2014', 'mm/dd/yyyy'))

或者,您可以使用CTE使用您的值创建伪表:

WITH serial_values as (
     select '1234' as serial, to_date('10/10/2014', 'mm/dd/yyyy') as c_date from dual
     union all
     select '5678' as serial, to_date('11/11/2014', 'mm/dd/yyyy') as c_date from dual)
SELECT   M.MODEL_NBR, DEV.SERIAL, i.c_date 
  FROM   device dev, 
         model m, 
         A_DEVICE ad, 
         INTR i 
 WHERE   (DEV.SERIAL, i.intr_id) IN 
            (select serial, max(t.intr_id) over (partition by t.part_id)
               from intr t 
                    cross join device d
                    join serial_values sv
                    on d.serial = sv.serial
                       and t.c_date < sv.c_date
              where t.part_id = AD.PART_ID 
                and d.device_id = ad.device_id
                and d.model_type = 'XX')
         AND M.MODEL_ID = DEV.MODEL_ID 
         and M.MODEL_NBR = '1111' 
         AND DEV.DEVICE_ID = AD.DEVICE_ID 
         AND AD.PART_ID = I.PART_ID 
         order by DEV.SERIAL;