我有一个模型,序列,日期列表(数据库中不存在日期)。我需要在提供给我的日期之前提取模型,序列号和最近的通话日期。我确实找到了一个使用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;
答案 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;