2013-08-03 54 views
1

難以讓sql從postgresql數據庫中進行報告。來自日誌表的Postgres日期報告

  • cohead:cohead_id,cohead_number,cohead_orderdate
  • 評論:COMMENT_ID,comment_source_id,COMMENT_DATE,COMMENT_TEXT

兩個可我有兩個表,有關列如下工作加入cohead_id = comment_source_id查找與訂單相關的所有評論。

當我們向我們的訂購準備服務提交訂單時,我們通過插入帶有相關訂單的文本「已提交」的評論進行登錄。當我們使用訂單準備服務關閉訂單時,我們爲該訂單插入「已開票」評論。

我想要做的是獲得一個時間段(比如上個月)的每一天的列表,並計算當天或之前提交但尚未開具發票的訂單數那天。

我遇到了一些概念問題,我嘗試過的連接速度很慢。

任何想法?

+0

。 。你能提供一些樣本數據和預期結果嗎? –

回答

2

拍攝日期'20130731','20130805'作爲示例的開始和結束日期,這個查詢將每天在這兩個日期之間返回您需要的數量。您可以更改真實查詢的參數。

;with cte as (
    select d::date as d 
    from generate_series('20130731', '20130805', interval '1 day') as d 
) 
select 
    cte.d, 
    count(o.cohead_id) as cnt 
from cte 
    left outer join cohead as o on 
     o.cohead_orderdate <= cte.d and 
     not exists (
      select * 
      from comment as c 
      where 
       c.comment_date <= cte.d and 
       c.comment_text = 'Invoiced' and 
       c.comment_source_id = o.cohead_id 
     ) 
group by cte.d 
order by cte.d 

請參閱SQL FIDDLE EXAMPLE - 您可以添加/刪除行並檢查它是否正常工作。

希望有所幫助。

UPDATE: 如果你想獲得提交日期,而不是訂單日期,你不必來查詢訂單表都:

;with cte as (
    select d::date as d 
    from generate_series('20130731', '20130805', interval '1 day') as d 
), cte2 as (
    select 
     c1.comment_date as submitted_date, 
     c2.comment_date as invoiced_date, 
     count(*) as cnt 
    from comment as c1 
     left outer join comment as c2 on 
      c2.comment_source_id = c1.comment_source_id and 
      c2.comment_text = 'Invoiced' 
    where c1.comment_text = 'Submitted' 
    group by c1.comment_date, c2.comment_date 
) 
select c1.d, sum(c2.cnt) 
from cte as c1 
    left outer join cte2 as c2 on 
     c2.submitted_date <= c1.d and 
     (c2.invoiced_date is null or c2.invoiced_date > c1.d) 
group by c1.d 
order by c1.d 

看到SQL FIDDLE與更新的查詢

更新2由於OP說他有查詢性能的問題,我試着用窗口函數編寫另一個。這個想法是獲取所有類型提交的日期計數減去發票類型的評論,然後獲得滾動總額。

;with cte1 as (
    select d::date as d 
    from generate_series('20130731', '20130805', interval '1 day') as d 
), cte2 as (
    select 
     greatest('20130731', c.comment_date) as comment_date, 
     c.comment_text, count(*) as cnt 
    from comment as c 
    where 
     c.comment_text in ('Invoiced', 'Submitted') and 
     c.comment_date <= '20130805' 
    group by greatest('20130731', c.comment_date), c.comment_text 
), cte3 as (
    select 
     coalesce(cs.cnt, 0) - coalesce(ci.cnt, 0) as cnt, 
     coalesce(cs.comment_date, ci.comment_date) as comment_date 
    from (select * from cte2 where comment_text = 'Submitted') as cs 
     full outer join (select * from cte2 where comment_text = 'Invoiced') as ci on 
      cs.comment_date = ci.comment_date 
) 
select c1.d, sum(c3.cnt) over (order by c1.d) 
from cte1 as c1 
    left outer join cte3 as c3 on c3.comment_date = c1.d 
order by c1.d 

SQL FIDDLE

+0

讓我走上正確的軌道。我需要添加一個查詢,而不僅僅是加入,所以我可以使用提交日期而不是訂單日期(它們可以不同)。但邏輯起作用。仍然需要一段時間才能運行,但由於它可能是一夜之間更新,所以沒什麼大不了的。謝謝您的幫助! – Dustin

+0

沒有問題,增加了另一個查詢,可能我會幫你消除性能問題。 –

+0

@Dustin對於這樣的大規模更新感到抱歉,但我認爲可能與查詢窗口功能將執行比以前的兩個查詢更好:)請參閱更新2 –