2016-12-31 54 views
0

以下查詢到Postgres數據庫灌裝在毛坯DATE_TRUNC與導軌

@interventos_2 = Intervento.where(['previsto >= ?', start_date]).group("DATE_TRUNC('week', previsto)").count 

分組生成哈希從該視圖可以提取數據如下

<% @interventos_2.each do |w| %> 
    <%= w[0].strftime('%Y-%W') %> <%= w[1] %><br /> 
<% end %> 

然而,如果有一個在我們關注的星期內,空白(計數= 0),年份和商業週期的順序看起來很奇怪或者有誤導性。

什麼是一種有效的方法來聲明範圍,然後用零填充空白周?

更新查詢與數據集的預期是足夠大的,經常變化正在通過specific sql for performance reasons運行(高速緩存可能無法幫助所有的東西)和常見。

+0

標準的SQL技巧,以免遺漏細胞在製表是使用*日曆表*和LEFT JOIN原始查詢到它。 – wildplasser

回答

1

如果我理解正確,您希望提供全套YYYY-WW標籤和計數,從start_date開始,無論某個星期是否有數據。您沒有提及previsto是日期,時間還是日期時間;我會認爲這是一個時間,只是爲了最大的不便。 =]

我認爲您所面臨的主要挑戰是您將數據集與演示文稿混合在一起。我喜歡分別處理兩個問題:首先,獲取數據並將其放入一週的格式;然後呈現範圍。

用於獲取數據,我喜歡更Railsy,更少數據庫特定的解決方案。您的里程可能會有所不同,特別是如果您有大型數據集和/或需要使數據庫完成繁重工作。這是一個查詢,它只獲取每個記錄的previsto字段,同時強制數據庫評估日期範圍。

@interventos_2 = Intervento.select(:previsto). 
    where(previsto: (start_date..Time.now)). 
    map {|iv| iv.previsto.strftime('%Y-%W')} 

注意,這也映射結果下來的YYYY-WW一個簡單的數組:也許不必SQL打出來的最簡潔的查詢。說到這,讓我們繪製出該範圍的YYYY-WW現在:

# make sure the end_date a clean multiple of 7 days from start_date 
end_date = Date.today + (7 - (Date.today - start_date.to_date) % 7) 
@timespan = (start_date.to_date..end_date).step(7).map {|date| date.strftime('%Y-%W')} 

(有寫,可能更爲整潔的方式)

鑑於這些位,這裏呈現完整的視圖代碼版本即使它是0,也是周的數量和計數:

<% @timespan.each do |yearweek| %> 
    <%= yearweek %> <%= @interventos_2.count(yearweek) %><br /> 
<% end %> 

在bocca al lupo!

更新:你更新的說明您的使用情況下需要直接使用SQL查詢,所以這裏的考慮與相同的一般方法:

@interventos_2 = Intervento.where(['previsto >= ?', start_date]). 
    group("DATE_TRUNC('week', previsto)").count. 
    map {|timestamp,count| [timestamp.strftime('%Y-%W'), count]}.to_h 

# make sure the end_date a clean multiple of 7 days from start_date 
end_date = Date.today + (7 - (Date.today - start_date.to_date) % 7) 
@timespan = (start_date.to_date..end_date).step(7).map {|date| date.strftime('%Y-%W')} 

<% @timespan.each do |yearweek| %> 
    <%= yearweek %> <%= @interventos_2[yearweek] || 0 %><br /> 
<% end %> 
+0

你絕對已經達到了表達元素所期望的簡潔性。打破SQL是出於性能原因(問題更新,以反映這種動機) – Jerome

+0

公平。修訂以反映您的情況。 –

0

用下面的控制方法,周的範圍和生成視圖所需的數據(除了數據本身之外,用於與已有數據進行比較的beginning_of_week)。

@weeks = [] 
while start_date < final_date 
    @weeks[start_date.year] = [] unless @weeks[start_date.year] 
    @weeks << [start_date.beginning_of_week, start_date.cweek] 
    start_date += 1.week 
end 
@weeks.reject!{|a| a.blank?} 

因此視圖可以生成用於每個星期的佈局信息並比較它的散列,並且其中有nil,生成零。

<% @weeks.each do |week| %> 
    <% if !week.nil? %> 
     <%= week[0] %>: 
     <% z = @interventos_2.detect {|f| f[0] == week[0] } %> 
     <% if !z.nil? %> 
     <%= z.to_a[1] %> 
     <% else %> 
     0 
     <% end %> 
    <% end %>