将条件应用于一个选定的列

时间:2018-02-28 15:25:26

标签: sql oracle

我有一个查询记录了2018年最后一次记录的事件和记录的事件总数。

在我的查询中,我必须将2018年应用于其中一个列。这是我的代码,让每个人都更容易理解:

select 1 as SortId, 'SouthEast' As "Region", NVL(COUNT(*),0) As "Recordable Events YTD"
from Table_name
WHERE 
IA_TYPE_TEXT IN('con_a','con_b','con_c')
AND
IA_PLANT IN('location_a','location_b','location_c')
AND
to_char(IA_DATE,'YYYY') = '2018' 

此代码将为我提供2018年东南部的可录制活动,结果如下:

    SORTID Region    Recordable Events YTD
---------- --------- ---------------------
         1 SouthEast                     0

这是我的第二个查询,以显示东南地区的最后一个事件

Select To_CHAR(TRUNC(max(IA_Date)),'MM/DD/YYYY') As "Incident Date"
from DOT.IA_LOG where IA_TYPE_TEXT IN('con_a','con_b','con_c')
AND
IA_PLANT IN('location_a','location_b','location_c')

结果是:

Incident Date
-------------
12/18/2017

我试图在一个结果中显示所有数据但是当我尝试将第二个select语句添加到第一个时,它给出了上一个事件日期的空结果,因为2018条件适用于它这是我的综合查询和结果。

select 1 as SortId, 'SouthEast' As "Region", NVL(COUNT(*),0) As "Recordable Events YTD",
  To_CHAR(TRUNC(max(IA_Date)),'MM/DD/YYYY') As "Last Recordable Event" 
from Table_name
WHERE 
IA_TYPE_TEXT IN('con_a','con_b','con_c')
AND
IA_PLANT IN('location_a','location_b','location_c')
AND
to_char(IA_DATE,'YYYY') = '2018' 

    SORTID Region    Recordable Events YTD Last Recordable Event
---------- --------- --------------------- ---------------------
         1 SouthEast                     0

如何将条件应用于其中一列?最简单的方法是什么?

2 个答案:

答案 0 :(得分:1)

使用cte(公用表表达式)代替。希望这可以帮助。感谢。

 with tmp as (select 1 as SortId, 
'SouthEast' As  rgn,
NVL(COUNT(*),0) As YTD
from Table_name
WHERE IA_TYPE_TEXT IN('con_a','con_b','con_c')
AND IA_PLANT IN('location_a','location_b','location_c')
AND to_char(IA_DATE,'YYYY') = '2018')
select tmp.SortId, 
rgn as "Region",
YTD as "Recordable Events YTD",
To_CHAR(TRUNC(max(IA_Date)),'MM/DD/YYYY') As "Incident Date" 
from DOT.IA_LOG, tmp
where IA_TYPE_TEXT IN('con_a','con_b','con_c')
AND IA_PLANT IN('location_a','location_b','location_c')
group by sortid,rgn,ytd

Result:
SortId  Region      Recordable Events YTD   Incident Date
1       SouthEast   0                       12/18/2017

答案 1 :(得分:1)

您可以使用条件计数,在count函数调用中包含case表达式,即:

COUNT(CASE WHEN to_char(IA_DATE,'YYYY') = '2018' then IA_DATE END)

并且没有当年的整体过滤器;原地:

select 1 as SortId,
  'SouthEast' As "Region",
  NVL(COUNT(CASE WHEN to_char(IA_DATE,'YYYY') = '2018' then IA_DATE END),0)
    As "Recordable Events YTD",
  To_CHAR(TRUNC(max(IA_Date)),'MM/DD/YYYY') As "Last Recordable Event" from IA_LOG
WHERE 
IA_TYPE_TEXT IN('con_a','con_b','con_c')
AND
IA_PLANT IN('location_a','location_b','location_c')
/

count函数只计算非空值;如果不满足条件,则case表达式的结果为null,因此不计算这些行。

使用虚拟数据可以得到问题中显示的相同结果:

    SORTID Region    Recordable Events YTD Last Recordable Event
---------- --------- --------------------- ---------------------
         1 SouthEast                     0 12/18/2017

不直接相关,但我个人更喜欢使用extract()来比较部分日期; count()无法返回null,因此不需要nvl();并且不需要trunc(),因为您的格式模型不包括时间。所以你可以略微简化为:

select 1 as sortid,
  'SouthEast' as "Region",
  count(case when extract(year from ia_date) = 2018 then ia_date end)
    as "Recordable Events YTD",
  to_char(max(ia_date), 'MM/DD/YYYY') as "Last Recordable Event"
from ia_log
where ia_type_text in('con_a', 'con_b', 'con_c')
and ia_plant in('location_a', 'location_b', 'location_c')

获得相同的结果。我也避免引用标识符,但可能会直接用于显示。