我正在尝试将MS-Access查询转换为postgres语句,以便我可以在SSRS中使用它。除了IIF声明外,似乎工作得很好。
.Site {
display: flex;
min-height: 100vh;
flex-direction: column;
}
.Site-content {
flex: 1;
}
它返回以下消息
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
(SELECT
ls_sort.ncm_id
, ls_sort.computer_name
, ls_sort.number_of_ops
, ls_sort.badge_scan_time
, ls_sort.sortby_employeeid
, Min(ls_sort.ncm_scan_time) AS MinNCMScanTime
, Max(ls_sort.updated_at) AS MaxUpdatedAt
FROM stone.ls_sort
INNER JOIN stone.ls ON ls_sort.ls_id = ls.ls_id
WHERE 1=1
AND ls_sort.created_at Between current_date-1 And current_date
GROUP BY ls_sort.ncm_id
, ls_sort.computer_name
, ls_sort.number_of_ops
, ls_sort.badge_scan_time
, ls_sort.sortby_employeeid
ORDER BY ls_sort.computer_name) AS labor_sort_1
我该如何解决这个问题?
答案 0 :(得分:11)
您需要将逻辑切换为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
由于您不必担心嵌套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
此外,您可以将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
答案 1 :(得分:1)
与@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.
寻找public-snippets-library时很好。
答案 2 :(得分:0)
我知道这已经存在了一段时间,但是另一个选择是创建用户定义的函数。如果您在互联网搜索中偶然发现此问题,那么这可能是您的解决方案。
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');
如果文本不让您喜欢,请尝试函数重载