2016-04-28 76 views
1

我可以通過查詢來獲得每月和每家商店18至24歲的顧客數量。 我在做這樣的:如何計算PostgreSQL在多個日期範圍內的出現次數

select year, month, shop_id, count(birthday) 
from customers 
where birthday 
BETWEEN '1992-01-01 00:00:00' AND '1998-01-01 00:00:00' 
group by year, month, shop_id; 

現在,我有一個問題,使這個查詢在同一時間幾個範圍。

我目前這個數據庫模式:

shop_id | birthday | year | month | 
--------+----------+------+-------- 
567 | 1998-10-10 | 2014 | 10 | 
567 | 1996-10-10 | 2014 | 10 | 
567 | 1985-10-10 | 2014 | 10 | 
234 | 1990-10-10 | 2014 | 10 | 
123 | 1970-01-10 | 2014 | 10 | 
123 | 1974-01-10 | 2014 | 11 | 

而且我想獲得這樣的事:

shop_id | year | month | 18 < age < 25 | 26 < age < 35 
--------+------+-------+---------------+------------- 
567 | 2014 | 10 | 2    | 1 
234 | 2014 | 10 | 1    | 0 
123 | 2014 | 10 | 0    | 0 

在第一個查詢,其中一個店有它不管理的情況下沒有客戶。如果沒有,如何獲得0?

如何同時查詢多個日期範圍?

+0

在選擇列表中有一個表達式,每個年齡組都有一個表達式。例如。 ',計數(當......然後1結束的情況下)爲18_age_25,計數(當...的時候爲 – jarlh

+0

年齡? –

回答

0

相反的過濾器,使用case語句:

select year, month, shop_id, 
count(case when birthday between <range1> then 1 end) RANGE1, 
count(case when birthday between <range2> then 1 end) RANGE2, 
count(case when birthday between <range3> then 1 end) RANGE3 
from customers 
group by year, month, shop_id; 
+1

非常感謝!簡單高效。 – KillianKemps

0

「不以零排」 是GROUP BY查詢的通病。解決方法是讓你的FROM成爲具有完整列表的任何表,然後執行LEFT JOIN。由於您按年份和月份分組,因此您需要輸出完整的年份和月份列表。你可以做到這一點與generate_series

SELECT t.t, s.id, COUNT(c.birthday) 
FROM shops s 
CROSS JOIN generate_series('2014-01-01 00:00:00', '2015-01-01 00:00:00', interval '1 month') t(t) 
LEFT OUTER JOIN customers c 
ON  c.shop_id = s.id 
AND  c.birthday 
     BETWEEN '1992-01-01 00:00:00' AND '1998-01-01 00:00:00' 
AND  c.year = EXTRACT(YEAR FROM t.t) 
AND  c.month = EXTRACT(MONTH FROM t.t) 
GROUP BY t.t, s.id 
ORDER BY s.id, t.t; 

要獲得數兩個日期範圍,你可以做MO2暗示什麼@,或者你可以加入到customers表兩次:

SELECT t.t, s.id, COUNT(DISTINCT c1.id), COUNT(DISTINCT c2.id) 
FROM shops s 
CROSS JOIN generate_series('2014-01-01 00:00:00', '2015-01-01 00:00:00', interval '1 month') t(t) 
LEFT OUTER JOIN customers c1 
ON  c1.shop_id = s.id 
AND  c1.birthday 
     BETWEEN '1992-01-01 00:00:00' AND '1998-01-01 00:00:00' 
AND  c1.year = EXTRACT(YEAR FROM t.t) 
AND  c1.month = EXTRACT(MONTH FROM t.t) 
LEFT OUTER JOIN customers c2 
ON  c2.shop_id = s.id 
AND  c2.birthday 
     BETWEEN '1982-01-01 00:00:00' AND '1992-01-01 00:00:00' 
AND  c2.year = EXTRACT(YEAR FROM t.t) 
AND  c2.month = EXTRACT(MONTH FROM t.t) 
GROUP BY t.t, s.id 
ORDER BY s.id, t.t; 

注意,在這兩個查詢我都是SELECT,而不是yearmonth。我認爲這更靈活,但如果你願意,應該很容易改變。

編輯:我意識到自己的yearmonth不是生日有關,但別的東西,我想訪問日期?所以我更新了我的查詢。如果您一次只檢查一個月,則可以刪除generate_series,並將年份和月份整數直接放入連接條件中。

相關問題