2014-08-27 81 views
1

我想計算產品顯示在兩個日期之間的事件。我必須填寫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 
+1

什麼是您的DBMS? – Dimt 2014-08-27 13:00:56

+0

與mssqlserver,你可以用transact-sql參數化存儲過程或函數編寫。我想其他dbms有類似的功能。 – user2504380 2014-08-27 13:05:31

+0

@Dimt:這是Oracle – ImportError 2014-08-27 13:06:10

回答

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

@Used_By_Already謝謝你用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只!

非常感謝!

+0

非常高興,謝謝你的反饋 – 2014-08-27 14:44:20