PostFres中的IIF

Dan*_*sch 5 postgresql

我试图将MS-Access查询转换为postgres语句,以便我可以在SSRS中使用它.除了IIF声明外,似乎工作得很好.

SELECT labor_sort_1.ncm_id
,IIf(labor_sort_1.sortby_employeeid = 3721
 , ((labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 29 * labor_sort_1.number_of_ops)
 , IIf(labor_sort_1.sortby_employeeid = 3722
  , ((labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops)
  , IIf(labor_sort_1.sortby_employeeid = 3755, ((labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops)
  , ((labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 17 * labor_sort_1.number_of_ops)))) AS labor_cost
FROM ...
Run Code Online (Sandbox Code Playgroud)

它返回以下消息 function iif(boolean, interval, interval) does not exist 我该如何解决这个问题?

Dan*_*sch 13

我知道这已经存在了一段时间,但另一个选择是创建用户定义的函数。如果您在互联网搜索中偶然发现了这一点,这可能是您的解决方案。

    CREATE FUNCTION IIF(
        condition boolean, true_result TEXT, false_result TEXT
    ) RETURNS TEXT LANGUAGE plpgsql AS $$
    BEGIN
     IF condition THEN
        RETURN true_result;
     ELSE
        RETURN false_result;
     END IF;
    END
    $$;

    SELECT IIF(2=1,'dan the man','false foobar');
Run Code Online (Sandbox Code Playgroud)

如果文本不能满足您的需求,请尝试函数重载


JNe*_*ill 12

您需要将逻辑切换到CASE语句.CASE语句是大多数RDBMS的标准,因此值得学习.在您的情况下(双关语意)它将转化为:

CASE 
    WHEN labor_sort_1.sortby_employeeid = 3721
        THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 29 * labor_sort_1.number_of_ops
    WHEN labor_sort_1.sortby_employeeid = 3722
        THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops
    WHEN labor_sort_1.sortby_employeeid = 3755
        THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops
    ELSE
        (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 17 * labor_sort_1.number_of_ops)
    END AS labor_cost
Run Code Online (Sandbox Code Playgroud)

由于您不必使用嵌套iif()问题并且所有这些都需要将更多的员工添加到硬编码的人工成本列表中,因此这看起来更清晰,这并不是什么大问题.

您可能还发现IN这里的条件对我们有利,因此您只需要两个WHEN子句:

CASE 
    WHEN labor_sort_1.sortby_employeeid = 3721
        THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 29 * labor_sort_1.number_of_ops
    WHEN labor_sort_1.sortby_employeeid IN (3722, 3755)
        THEN (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 24 * labor_sort_1.number_of_ops
    ELSE
        (labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) * 24 * 17 * labor_sort_1.number_of_ops)
    END AS labor_cost
Run Code Online (Sandbox Code Playgroud)

此外,您可以将CASE语句移动到等式中,只需输出您希望乘以的任何数字:

(labor_sort_1.MaxUpdatedAt - labor_sort_1.MinNCMScanTime) 
    * 24    
    * CASE  
        WHEN labor_sort_1.sortby_employeeid = 3721 THEN 29
        WHEN labor_sort_1.sortby_employeeid IN (3722,3755) THEN 24
        ELSE 17
        END 
    * labor_sort_1.number_of_ops AS labor_cost
Run Code Online (Sandbox Code Playgroud)


Pet*_*uss 11

与@Daniel 的答案相同,但适用于任何数据类型。

CREATE or replace FUNCTION iIF(
    condition boolean,       -- IF condition
    true_result anyelement,  -- THEN
    false_result anyelement  -- ELSE
) RETURNS anyelement AS $f$
  SELECT CASE WHEN condition THEN true_result ELSE false_result END
$f$  LANGUAGE SQL IMMUTABLE;

SELECT iif(0=1,1,2);
SELECT iif(0=0,'Hello'::text,'Bye');  -- need to say that string is text.
Run Code Online (Sandbox Code Playgroud)

当您正在寻找public-snippets-library时很好。