我想计算两个日期之间事件中展示的产品。我必须填写9列,每列都有其他产品类型。
我想问你是否有可能缩短这一说法。 下面的sql是第一个工作但不是有效的尝试。
with events(event_id, customer_id) as (
select * from event
where start_date >= :stare_date
and end_date <= :end_date
),
select
(select count(*) from event_product where event_id in (select event_id from events where customer_id = customer.customer_id) and product_type = 'YLW') customer_ylw_products -- it works but its ugly and non effective
-------
-- repeat seven times for other type of products
-------
(select count(*) from event_product where event_id in (select event_id from events where customer_id = customer.customer_id) and product_type = 'RTL') customer_rtl_products
from customer
;
注意该行
(select event_id from events where customer_id = customer.customer_id)
重复约9次。
我一直试图通过添加以下内容来缩短这个:
with events(event_id, customer_id) as (
select * from event
where start_date >= :stare_date
and end_date <= :end_date
),
**customer_events (event_id, customer_id) as (select * from events)**
select
(select count(*) from event_product where event_id in (select event_id from customer_events) and product_type = 'RTL') customer_rtl_products
from customers
where customer_events.customer_id = customer.customer_id -- doesnt works
having customer_events.customer_id = customer.customer_id -- doesnt works
答案 0 :(得分:1)
为什么不使用案例表达式?
WITH
events (event_id, customer_id)
AS (
SELECT
*
FROM event
WHERE start_date >= :stare_date
AND end_date <= :end_date
)
SELECT
*
FROM customer
LEFT JOIN (
SELECT
event_product.customer_id
, COUNT(CASE
WHEN event_product.product_type = 'YLW' THEN 1 END) AS count_YLW
, COUNT(CASE
WHEN event_product.product_type = 'RTL' THEN 1 END) AS count_RTL
FROM event_product
INNER JOIN events
ON event_product.event_id = events.event_id
GROUP BY
event_product.customer_id
) ev_counts
ON customer.customer_id = ev_counts.customer_id
;
如果您愿意,也可以在没有CTE的情况下执行此操作,只需将您当前在CTE中使用的内容用作派生表,其中events
现在放在内部联接中。
脚注select *
只是方便我不知道要使用哪些字段,但应该指定它们。
答案 1 :(得分:1)
@Used_By_已经感谢您通过event_product和event之间的内部联接启发我,并且Event_product没有列customer_id所以我只是添加了它!
那是我的解决方案
with events(event_id, customer_id) as (
select * from event
where start_date >= :stare_date
and end_date <= :end_date
),
product_events (customer_id, product_type) as (
select event.customer_id, event_product.product_type
from events,event_product
where event_product.event_id = event.event_id and event_product.product_type in (''product_types'')
)
select
(select count(*) from product_events where customer_id = customer.customer_id and product_type = 'RTL') customer_rtl_products
from customers;
搜索中50行的性能从45秒增加到仅5行!
非常感谢你!