2013-07-23 42 views
1

我有一個表,每個點都有一個時間屬性(列「小時」),位於一個砂礫的不同方塊中(由「gridid」列標記)。通過forloop替換多個左連接

對於每個正方形,我想獲得按小時分組的點數,從而得到一個具有24列+與現有gridid相同數量的行的表格。

到目前爲止,我用24個左連接(下圖)做了這個。有簡單的循環來簡化查詢嗎?

SELECT * from (select gridid, count(id) as "00" from points where hour = 0 GROUP BY gridid ORDER BY "00" DESC)t00 

left join 
(select gridid, count(id) as "01" from points where hour = 1 GROUP BY gridid)t01 
on t01.gridid = t00.gridid 

left join 
(select gridid, count(id) as "02" from points where hour = 2 GROUP BY gridid)t02 
on t02.gridid = t00.gridid 

... 

left join 
(select gridid, count(id) as "24" from points where hour = 24 GROUP BY gridid)t02 
on t02.gridid = t24.gridid 

回答

1

FOR循環在SQL中通常是一個壞主意,它對於基於集合的操作符效果更好。相反,你可以試試:(順便說一句,列00和24是不可能都被填充,除非您使用的是25小時制)

select grid_id, 
     sum(case hour when 0 then 1 end) as "00", 
     sum(case hour when 1 then 1 end) as "01", 
     sum(case hour when 2 then 1 end) as "02", 
... 

     sum(case hour when 24 then 1 end) as "24" 
from points 
group by grid_id 
order by 2 desc 

+0

感謝yoo,這可能會縮短查詢時間,但想象一下,我將不得不每年365天做類似的事情。 –

+0

@Berlin_J:爲什麼?你的問題涉及一天中的幾小時,而不是一年中的幾天 - 今年的幾天是如何相關的? **如果**它們是相關的,請您可以更新您的問題以反映您希望**回答的問題**,而不是您問** **的問題。 –

+0

我只是想知道我通常可以避免這些鏈條。我只提到365天的例子來強調我想在我的查詢中改進的內容。你如何看到上面,我已經有一個情況下的解決方案之前,我寫我的問題... –

0

在一般情況下,我同意,這是使用for循環替換任何類型的連接幾乎總是一個壞主意。當PostgreSQL是最合適的加入方法時,它將使用循環。特別是,一個FOR循環不會給你任何正常的連接,而且它意味着在規劃人員可以獨立完成的工作中對規劃人員進行微觀管理。

現在在你的情況下,你不想要一個循環。你有三個選擇。

  1. 可以使用CASE的方式馬克·班尼斯特表明above.A

  2. 你可以只返回一組,並在客戶端轉動它。像

    SELECT grid_id, count(id), hour 
        FROM points 
    GROUP BY grid_id, hour 
    ORDER BY grid_id, hour; 
    
  3. 東西,你可以使用crosstab()功能在tablefunc轉動上面的查詢中 PostgreSQL的。這可能需要一些練習,但請參閱關於 的tablefunc文檔。