裏面一個大的查詢主叫COUNT兩次,我必須COUNT變量,然後如果它大於1,具有計數作爲字符串否則空字符串:避免在CASE表達式(PostgreSQL的)
CASE COUNT(measurement.id) > 1 THEN to_char(COUNT(measurement.id),' 999') ELSE ''
恐怕這很慢,因爲我使用COUNT()兩次。有沒有更好的辦法?
裏面一個大的查詢主叫COUNT兩次,我必須COUNT變量,然後如果它大於1,具有計數作爲字符串否則空字符串:避免在CASE表達式(PostgreSQL的)
CASE COUNT(measurement.id) > 1 THEN to_char(COUNT(measurement.id),' 999') ELSE ''
恐怕這很慢,因爲我使用COUNT()兩次。有沒有更好的辦法?
這個表達式:因爲COUNT()
被稱爲兩次
CASE COUNT(measurement.id) > 1 THEN to_char(COUNT(measurement.id),' 999') ELSE ''
不慢。彙總數據的艱鉅工作是將關鍵值集中在一起的部分。單獨的聚合功能通常不是特別昂貴(有例外,如COUNT(DISTINCT)
)。所以,即使它被多次調用,這也不是問題。
你可以查詢更改爲更具神祕狀:
coalesce(to_char(nullif(count(measurement.id), 0), '999')), '')
這需要的計數爲0,將其轉換爲NULL
,然後將其變成一個空字符串(我認爲它會只在Postgres中評估一次參數,儘管SQL Server會評估它兩次,在這種情況下,您使用isnull()
而不是coalesce()
)。我更喜歡你的版本,如果你覺得有必要把漂亮的數字轉換成字符串。
編輯:
COUNT()
似乎被定義爲「不可變的」,這是比「穩定的」甚至更強。我甚至不確定這是否正確,但SQL Fiddle就是這種情況。無論如何,它可能不會被調用兩次,但昂貴的部分無論如何都是GROUP BY
。
(對於這篇小論文,我有點不高興了......)聚合實際上並沒有一個公開的穩定課。 'pg_proc'中的條目只是一個佔位符,用來保留函數簽名,並防止在非聚合上下文中調用(注意'prosrc'只是['aggregate_dummy'](https://github.com/postgres) /postgres/blob/aa9eac45ea868e6ddabc4eb076d18be10ce84c6a/src/backend/executor/nodeAgg.c#L2888),所以'IMMUTABLE'可能適合)。 –
穩定性類的整體概念不能(很容易)在這裏應用,因爲明顯的行爲(將一個集映射到標量值的函數)與現實非常不同(驅動一系列狀態轉換的一系列值) 。大多數轉換函數在技術上都是'VOLATILE',儘管它們有聲明,因爲它們在累加器上執行就地更新。 'COUNT()'函數有點違背分類,因爲它實際上修改了它的輸入...... –
除此之外,聚合的行爲就像'STABLE'一樣(即使它們不是):[SQLFiddle](http ://www.sqlfiddle.com/#!15/70ef4/1) –
計數只會被評估一次。 –
那會很棒,是在文檔的某處? – RemcoGerlich
@RemcoGerlich。 。 。波動性的定義非常強烈(http://www.postgresql.org/docs/9.4/static/xfunc-volatility.html)。我認爲這適用於聚合函數,並且'COUNT()'被正確聲明爲穩定。 –