映射没有表的值

Key*_*eyo 6 sql database postgresql

我需要使用地图year根据值来分配特定值year_code.目前我有一个很大的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
Run Code Online (Sandbox Code Playgroud)

显而易见的解决方案是使用表并选择一个值,但是我已经被指示将其全部保留在一个postgres函数中,以便快速完成.后来我计划将所有这些存储在表格中.

那么有没有办法我可以创建一个临时地图并选择它来获得年份的价值.真的,我只想清理这个丑陋的代码.谢谢.

one*_*hen 13

在函数中使用公用表表达式(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 ...;
Run Code Online (Sandbox Code Playgroud)

或者,派生表:

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

也许后来的基表可以是日历表.


mu *_*ort 5

快速而肮脏的解决方案将是一个丑陋的大 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;
Run Code Online (Sandbox Code Playgroud)

我不知道这是否比一堆丑陋的 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;
Run Code Online (Sandbox Code Playgroud)

我想问题是你想要哪种风格的丑陋黑客。