2017-04-03 75 views
0

我試圖顯示按項目狀態過濾的每月所有項目的累計數 - 'raw','finished','lost'。我使用的數據庫是PostgreSQL。底部的最新查詢與我正在查找的內容接近,但即使該月沒有條目,我也想顯示每個「狀態」的總計數。目前在第3,4和5個月 - 計數爲空。會在這裏滯後/領導工作嗎?或者也許另一種方法。 我試圖說明問題儘可能簡單。在SQL中遞歸項目移動

實施例:

id created_at lastmodified closed_at status 
1 2/22/2016 6/21/2016      Raw 
2 2/4/2016 6/21/2016      Raw 
3 8/21/2016 8/26/2016      Raw 
4 8/12/2016 8/26/2016      Raw 
5 2/8/2016 6/21/2016      Raw 
6 8/2/2016 8/26/2016      Raw 
7 6/14/2016 6/29/2016 6/23/2016  Finished 
8 2/12/2016 6/21/2016      Raw 
9 8/18/2016 8/26/2016      Raw 
10 8/8/2016 8/26/2016 8/26/2016  Finished 
11 8/26/2016 8/26/2016      Raw 
12 8/5/2016 8/26/2016      Raw 
13 2/30/2016 2/30/2016 2/30/2016  Finished 
14 6/22/2016 7/19/2016 7/27/2016  Finished 
15 8/12/2016 8/28/2016      Raw 
16 9/20/2016 10/16/2016     Raw 
17 2/15/2016 6/11/2016      Raw 
18 2/6/2016 9/24/2016      Lost 

我要顯示的條形圖通過時間描繪項的移動,每月的基礎上,(說從01-16至04-16,在此實例中),使得item3也將有一個02-16的原始數據庫,但它沒有數據庫中的條目,但是因爲它的上一個已知狀態是'原始的'應該被考慮。
我認爲需要一個CTE(公共表表達式)來生成一個日期表以消耗給定時間段內的所有日期。

with dates as(
select * from generate_series('2016-01-01'::date, 
    '2017-04-01'::date, 
    '1 day'::interval) 

查詢結果應該是什麼樣子,基本的運行計數的總所有項目如何有每個狀態的每個月底。

month/yr  raw  finished  lost 
2/2016   5   1  0 
3/2016   6   0  0 
4/2016   7   0  0 
5/2016   7   0  0 
6/2016   8   2  0 
7/2016   7   3  0 
8/2016   13   4  0 
9/2016   13   0  1 
sum    13   4  1 

有三個階段 - 原材料,成品,lost.You是正確的假設,raw只能要麼create_at或modified_at,而finished - 可以擁有所有三個字段填寫created_atmodified_atclosed_at。但是,只有當狀態更改爲finished時,纔會填寫closed_at。 Lost商品也只能有created_atmodifieddate。創建時的所有項目默認情況下都會達到raw的狀態。 達到狀態finished的項目將永遠不會獲得其他日期條目,但我想顯示該狀態的項目累計數量。

WITH dates as(
    SELECT * FROM generate_series('2016-02-01'::date, '2016-06-01'::date, 
    '1 month'::interval) 
), 
step AS (
    SELECT a.Id, 
    'Raw' AS Step, 
    a.Created_at AS FDate, 
    b.TDate 
    FROM sales a 
    LEFT JOIN 
    (SELECT 
    a.Id, 
    CASE WHEN a.lastmodified IS NULL THEN now() ELSE a.lastmodified END AS TDate 
    FROM sales a 
    WHERE a.lastmodified IS NOT NULL AND a.Status like 'Raw') b 
    ON a.Id = b.Id 
    WHERE a.created_at IS NOT NULL 

    UNION 
    SELECT a.Id, 
    'Lost' AS Step, 
    a.lastmodified AS FDate, 
    b.TDate 
    FROM sales a 
    LEFT JOIN 
    (SELECT a.Id, 
    CASE WHEN a.lastmodified IS NULL THEN now() ELSE a.lastmodified END AS ToDate 
    FROM sales a 
    WHERE a.closed_at IS NOT NULL AND a.Status like 'Finished') b 
    ON a.Id = b.Id 
    WHERE a.lastmodified IS NOT NULL AND a.Status like 'Lost' 

    UNION 
    SELECT a.Id, 
    'Finished' AS Step, 
    a.closed_at::date AS FDate, 
    now() AS TDate 
    FROM sales a 
    WHERE a.closed_at IS NOT NULL AND a.Status like 'Finished' 
) 
    SELECT DISTINCT to_char(d.generate_series::date, 'YYYY-MM') AS date, s.Step AS Status, 
    COUNT(s.Step) OVER (PARTITION BY s.Step ORDER BY to_char(d.generate_series, 'YYYY-MM')) AS count_id 
    FROM dates d 
    LEFT JOIN step s 
    ON to_char(d.generate_series::date,'YYYY-MM') = to_char(s.FDate::date, 'YYYY-MM') 
    ORDER BY date ASC 

此查詢使我非常接近我所尋找的。但是,對於沒有創建,修改或關閉項目的月份,我的計數爲零。如果沒有條目,我想顯示上個月的累計數。我怎麼做到這一點?會在這裏滯後/領導工作嗎?

+0

你想查詢結果看起來像什麼東西?忽略圖表,這是完全不同的問題。 –

+0

01-01-2016爲什麼顯示3? –

+0

我投票結束這個問題,因爲你沒有提供足夠的信息來回答它。 –

回答

0

好像

  1. 的一切,是不是finished,是raw
  2. finished只能有closed_at
  3. raw只能有created_atmodified_at
  4. 你要我們承擔的東西raw之前的所有時間點created_at
  5. 您希望事情在該時間點完成後顯示完成?

請澄清你想要什麼。最好顯示樣本數據和最終結果。

所有的說,我覺得你想要的是類似這樣的

SELECT d, CASE WHEN d < stat.min THEN 'raw' ELSE 'finished' END 
FROM (VALUES 
    ('2016-01-01'::date, '2017-04-01'::date) 
) AS t(date_start,date_end) 
CROSS JOIN LATERAL generate_series(date_start, date_end, '1 day') 
    AS gs(d) 
CROSS JOIN (
    SELECT min(closed_at) 
    FROM foo 
    WHERE item_id = 'item3' 
    GROUP BY item_id 
) AS stat; 
+0

感謝您的回答。我更新了查詢。 – OAK