在 oracle 的 sql 查询中替换“过滤器”

Posted

技术标签:

【中文标题】在 oracle 的 sql 查询中替换“过滤器”【英文标题】:substituting "filter" in a sql query on oracle 【发布时间】:2022-01-03 02:46:48 【问题描述】:

我们有一个数据表,其中一个日期列指示数据的日期(“planning_day”)和另一个用于记录数据发送时间的列(“first_sent_time”)。

我正在尝试制作一份报告,显示过去/未来我们在哪一天发送了多长时间的数据。因此,如果今天我们发送 2 个昨天的数据,5 个今天的数据,1 个后天的数据,结果应该是这样的:

sent_day   minus2 minus1 sameDay plus1 plus2
2021-11-24    0      2      5      0     1
...

我知道我可以在 postgres 中使用“过滤器”进行查询:

select
  trunc(t.first_sent_time),
  count(t.id) filter (where e.planning_day - trunc(e.first_sent_time) = -2) as "minus2",
  count(t.id) filter (where e.planning_day - trunc(e.first_sent_time) = -1) as "minus1",
  count(t.id) filter (where e.planning_day - trunc(e.first_sent_time) = 0)  as "sameDay",
  count(t.id) filter (where e.planning_day - trunc(e.first_sent_time) = 1)  as "plus1",
  count(t.id) filter (where e.planning_day - trunc(e.first_sent_time) = 2)  as "plus2"
from
  my_table t
group by
  trunc(t.first_sent_time)
;

不幸的是,这个“过滤器”在 Oracle 中不存在。我在这里需要帮助。我尝试了以下方法:

select 
  sent_day,
  sum(minus2),
  sum(minus1),
  sum(sameDay),
  sum(plus1),
  sum(plus2)
from (
  select 
    *
  from (
    select
      b.id,
      trunc(b.first_sent_time) as sent_day,
      b.planning_day,
      b.planning_day - trunc(b.first_sent_time) as day_diff
    from
      my_table b
    where
      b.first_sent_time >= DATE '2021-11-01'
  )
  pivot (
    count(id) for day_diff in (-2 as "minus2",-1 as "minus1",0 as "sameDay", 1 as "plus1",2 as "plus2")
  )
)
group by
  sent_day
order by
  sent_day
;

但它不起作用,感觉我太复杂了,必须有一个更简单的解决方案。

【问题讨论】:

【参考方案1】:

在聚合函数中使用CASE表达式来模拟filter

这里是一个简化的例子

with dt as (
select 1 id , 1 diff_days from dual union all
select 2 id , 1 diff_days from dual union all
select 3 id , -1 diff_days from dual union all
select 4 id , -1 diff_days from dual union all
select 4 id , -1 diff_days from dual)
/* query */
select 
  count(case when diff_days = 1 then id end) as cnt_1,
  count(case when diff_days = -1 then id end) as cnt_minus_1
from dt;

结果

     CNT_1 CNT_MINUS_1
---------- -----------
         2           3

【讨论】:

以上是关于在 oracle 的 sql 查询中替换“过滤器”的主要内容,如果未能解决你的问题,请参考以下文章

使用 Oracle 替换变量进行查询

oracle sql语句中的替换问题

oracle sql 字符串拆分的查询的问题,急!!!

Java + Oracle 中的 SQL 查询

Oracle 中 查询结果替换的问题

在 oracle sql 12c 中可以绕过分区吗?