2011-05-23 85 views
3

我需要使用映射根據值year_code具有的值將值分配給year。目前我有一個很大的if語句,顯然很難維護。無表映射值

IF year_code = 'Y' THEN year := 2000; END IF; 
IF year_code = '1' THEN year := 2001; END IF; 
IF year_code = '2' THEN year := 2002; END IF; 
-- and so on 

明顯的解決辦法是使用一個表,並選擇一個值,但是我已經指示要保持它的所有的一個Postgres的函數中爲得到它幹得快的緣故。稍後,我計劃將所有這些存儲在表格中。

那麼有沒有一種方法可以創建一個臨時地圖並選擇它的形式來獲得一年的價值。真的,我只想清理這個醜陋的代碼。謝謝。

+0

當我查看數據時,使用表格更好。使用另一個表並使該表引用您的父表。 – vkrams 2011-05-23 05:20:25

+0

我希望我能,而且會在稍後做這件事。但我現在被指示要做一些快速而骯髒的事情。 – Keyo 2011-05-23 05:24:54

+0

@mu看起來像一個不錯的工具。然而'類型「hstore」不存在'。 – Keyo 2011-05-23 05:27:54

回答

9

在你的函數中使用一個Common Table Expression (CTE)可以很容易地在稍後的例子中用基表替換CTE。

WITH YearCodes (year_code, year) AS 
    (SELECT year_code, year 
     FROM (VALUES ('Y', 2000), 
         ('1', 2001), 
         ('2', 2002)) 
       AS YearCodes (year_code, year)) 
SELECT ...; 

可替換地,派生表:

SELECT * 
    FROM (VALUES ('Y', 2000), 
       ('1', 2001), 
       ('2', 2002)) 
     AS YearCodes (year_code, year) 
     -- other stuff here; 

也許這稍後基表可以是calendar table

+0

太好了,正是我在找的東西。 – Keyo 2011-05-23 21:32:12

+0

我已經通知一些數據庫節點在PostgreSQL 8.1上,這不起作用。 :( – Keyo 2011-05-24 01:42:34

+0

@Keyo:派生表怎麼樣?我已經更新了我的答案。 – onedaywhen 2011-05-24 07:18:01

3

我建議你創建一個臨時表並用你的數據填充它。然後你可以鏈接表格並轉換數據。雖然這對於一個SQL語句看起來可能有很多工作,並且可能有更快捷的方法,但這會爲您準備好創建單獨的表格時提供很好的幫助。然後,您可以刪除臨時表語句和INSERT語句,只需將您正在鏈接的表名從臨時表更改爲新創建的表。

我看到的唯一其他相當乾淨的解決方案是轉換數據而不是使用If語句。例如,如果2000年是唯一一個字母,那麼你可以做一個if語句,如果它是Y(並將其轉換爲),而另一個是,如果它不是Y,則年份爲2000年+ year_code 。如果你的年齡與此相匹配,那麼現在這將是一種相當簡單的做事方式。

3

快速和骯髒的解決方案將是一個大丑CASE語句:

CASE year_code 
    WHEN 'Y' THEN year := 2000 
    WHEN '1' THEN year := 2001 
    -- ... 
    ELSE year := NULL -- Or something else that makes sense or will 
         -- blow up so you know something is wrong. 
END CASE; 

我不知道這是不是一個大丑一堆的IF更好雖然。

你可以使用一個臨時表,但你必須將大量難看的數據存儲在某處,並且你必須檢查臨時表是否已經存在,如果不存在,就填充它。

你說你沒有hstore由你可以用PostgreSQL的陣列和WHILE循環假冒安裝它:

-- Untested "off the top of my head" code 
array := ARRAY['Y', '2000', '1', '2001', /* ... */ ]; 
i  := 1; 
WHILE i <= array_length(array) LOOP 
    IF year_code = array[i] THEN 
     year := array[i + 1]::INTEGER; 
     EXIT; -- Found it so bust out of the loop. 
    ELSE 
     i := i + 2; 
    END IF; 
END LOOP; 

我想這是一個醜陋的黑客的味道,你想要一個問題。

+1

如果OP必須使用臨時表,那麼使用表格可能更有意義。(一個普通的基表,不是臨時表) – 2011-05-24 12:04:03

+0

@Catcall:我可能也會使用表格,但是我只提到過,因爲有人提出了它,我想補充一些注意事項。 – 2011-05-24 16:38:51