2014-12-12 2 views
0

모델, 일련 번호, 날짜 목록이 있습니다 (날짜는 DB에 없습니다). 나에게 주어진 날짜 이전에 모델, 연재물, 가장 최근의 전화 날짜를 가져와야합니다. CASE를 사용하여 작동하는 "솔루션"을 찾았지만 더 간단한 방법이 있는지 궁금해하고있었습니다. 100 개 이상의 항목 목록을 가지고있을 때 OR CASE 문은 약간 힘들어합니다.Oracle SQL은 목록에 날짜를 비교합니다

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

WHERE 절에 CASE은 거의 항상 더 나은 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; 
+0

거의 모두 같은 시간에 데이터를 반환하는 것처럼 보입니다.하지만 솔루션이 조금 더 깨끗 해지거나 느껴집니다. 어쩌면 내가 그걸 생각 해냈다. 감사. – user3407090