我有一个sql查询,它基本上查询包含两列的表:event_name和event_count。
event_count是一个整数,表示事件执行的秒数。我编写了下面的查询,将事件汇总到层,即1-5秒,5-10秒等,这样我们就可以确定每个执行的时间。
我想知道是否有更好的方法去做我在下面做的事情,因为我不认为这是目前非常优化的,因为它必须在每个案例中运行sum()。
我尝试将之前选择的列(d_event_count)放在case语句中,如下所示:
(CASE WHEN d_event_count >= 0 and d_event_count < 5 THEN d_event_count ELSE 0 END) as d_time_1_5,
但它失败,表明表中不存在列,所以我在这里寻求帮助:)
select
event_name as d_event_name,
sum(event_count) as d_event_count,
(CASE WHEN sum(event_count) >= 0 and sum(event_count) < 5 THEN sum(event_count) ELSE 0 END) as d_time_1_5,
(CASE WHEN sum(event_count) >= 5 and sum(event_count) < 10 THEN sum(event_count) ELSE 0 END) as d_time_5_10,
(CASE WHEN sum(event_count) >= 10 and sum(event_count) < 15 THEN sum(event_count) ELSE 0 END) as d_time_10_15,
(CASE WHEN sum(event_count) >= 15 and sum(event_count) < 30 THEN sum(event_count) ELSE 0 END) as d_time_15_30,
(CASE WHEN sum(event_count) >= 30 and sum(event_count) < 45 THEN sum(event_count) ELSE 0 END) as d_time_30_45,
(CASE WHEN sum(event_count) >= 45 and sum(event_count) < 60 THEN sum(event_count) ELSE 0 END) as d_time_45_60,
(CASE WHEN sum(event_count) >= 60 and sum(event_count) < 120 THEN sum(event_count) ELSE 0 END) as d_time_60_120,
(CASE WHEN sum(event_count) >= 120 and sum(event_count) < 180 THEN sum(event_count) ELSE 0 END) as d_time_120_180,
(CASE WHEN sum(event_count) >= 180 and sum(event_count) < 240 THEN sum(event_count) ELSE 0 END) as d_time_180_240,
(CASE WHEN sum(event_count) >= 240 and sum(event_count) < 300 THEN sum(event_count) ELSE 0 END) as d_time_240_300,
(CASE WHEN sum(event_count) >= 300 THEN sum(event_count) ELSE 0 END) as d_time_300
from
product_events
where
...
group by 1
不可能更改表结构,还有许多其他列,这只是一个精简表示。
有人能帮助我吗?
答案 0 :(得分:0)
尝试这种方式,它使用d_event_count的累积和:
create temp table ev as
select *
from (
values
('event 1'::text, 5::int),
('event 2'::text, 5::int),
('event 3'::text, 5::int),
('event 4'::text, 5::int),
('event 5'::text, 5::int),
('event 6'::text, 5::int),
('event 7'::text, 5::int),
('event 8'::text, 5::int),
('event 9'::text, 5::int)
) t (event_name, d_event_count);
with sm as
(
select event_name, sum(d_event_count) over (order by event_name) as total
from ev
)
select event_name, total,
case when total between 0 and 5 then 'd_time_1_5'
when total between 6 and 10 then 'd_time_6_10'
when total between 11 and 15 then 'd_time_11_15'
else 'more than 15'
end as d_name
from sm;
+------------+-------+--------------+
| event_name | total | d_name |
+------------+-------+--------------+
| event 1 | 5 | d_time_1_5 |
+------------+-------+--------------+
| event 2 | 10 | d_time_6_10 |
+------------+-------+--------------+
| event 3 | 15 | d_time_11_15 |
+------------+-------+--------------+
| event 4 | 20 | more than 15 |
+------------+-------+--------------+
| event 5 | 25 | more than 15 |
+------------+-------+--------------+
| event 6 | 30 | more than 15 |
+------------+-------+--------------+
| event 7 | 35 | more than 15 |
+------------+-------+--------------+
| event 8 | 40 | more than 15 |
+------------+-------+--------------+
| event 9 | 45 | more than 15 |
+------------+-------+--------------+
使用WINDOW函数的另一种解决方案:
select event_name, sum(d_event_count) over w1 as total,
case when sum(d_event_count) over w1 between 0 and 5 then 'd_time_1_5'
when sum(d_event_count) over w1 between 6 and 10 then 'd_time_6_10'
when sum(d_event_count) over w1 between 11 and 15 then 'd_time_11_15'
else 'more than 15'
end as d_name
from ev
WINDOW w1 AS (order by event_name);