2010-02-18 115 views
1

我寫了一個遞歸函數,根據輸出我需要選擇不同的字段。我現在的問題是,如何多次執行此操作而不必多次調用該函數?我現在正在做的就是使用CASE WHEN...條件並每次檢查函數返回的結果。 (這只是一個僞代碼,並沒有做任何事情真實的,它只是爲了理解)PostgreSQL有條件的選擇

SELECT 
id, 
(CASE WHEN (function(id) > 0) 
    THEN field1 
    ELSE field2 
END) as value1, 
(CASE WHEN (function(id) > 0) 
    THEN field3 
    ELSE field4 
END) as value2, 
(CASE WHEN (function(id) > 0) 
    THEN field5 
    ELSE field6 
END) as value3 
FROM table1 
... 

如何優化這個查詢和調用該函數只有一次? 在此先感謝!

+0

有什麼功能的語言沒有什麼經驗? – 2010-02-18 13:51:02

+0

語言是PL/pgSQL。 – stefita 2010-02-18 14:02:45

+0

您接受使用IMMUTABLE的答案很奇怪,但您在評論中說您的函數「從另一個表中選擇了一個值,並且可以爲該特定ID進行更改」。我希望你沒有標記IMMUTABLE函數,因爲Postgres沒有說它緩存了不可變函數結果的時間。 – 2010-03-03 11:29:38

回答

2

如果函數聲明IMMUTABLE,它是安全地調用了很多次,因爲它不會被重新評估。

docs

IMMUTABLE表示該函數不能修改數據庫,並給出了相同的參數值時總是返回相同的結果;也就是說,它不會執行數據庫查找或以其他方式使用不直接存在於其參數列表中的信息。如果給出這個選項,任何具有所有常量參數的函數調用都可以立即替換爲函數值。

+0

如果相同參數的結果發生變化,會發生什麼? – stefita 2010-02-18 14:05:07

+0

@stefita:您不應該將這些功能標記爲「IMMUTABLE」。 http://www.postgresql.org/docs/current/static/xfunc-volatility.html – Quassnoi 2010-02-18 14:14:02

+0

@stefita:你的意思是像clock_timestamp()?然後你聲明它是VOLATILE,Postgres每次看到它時都會調用它。還有什麼可能呢?但你的例子看起來像函數(id)返回相同的東西,但你需要它來選擇3個不同的字段 – 2010-02-18 14:14:11

2

使用子查詢:

​​
1

您可以使用一些時髦的元組的事情,如:

SELECT id, 
CASE WHEN function(id) > 0 
    THEN (field1, field3, field5) 
    ELSE (field2, field4, field6) 
END as (value1, value2, value3) 

,但我有這個語法