我有一个 Postgres 数据库,其中有一个名为
servers
的表,其中包含以下列:
一些合规值并不像“通过”或“失败”那样黑白分明。因此,我首先使用
com_passfail
表达式生成 CASE
,仅包含“PASS”/“FAIL”。os_passfail
。
最后,我像这样生成overall_status
:
如果
com_passfail
或 os_passfail
为“通过”,则新列 overall_status
为“通过”。com_passfail
或 os_passfail
为“FAIL”且 ref_id
不为 NULL,则 overall_status
为“PASS”。com_passfail
或 os_passfail
为“FAIL”且 ref_id
为 NULL,则 overall_status
为“FAIL”。
表的示例行
servers
:
服务器 | 合规 | 操作系统 | ref_id |
---|---|---|---|
服务器1 | 通过 | 好的 | |
服务器2 | 好 | 不好 | |
服务器3 | 好的 | 有效 | |
服务器4 | 失败 | 通过 | |
服务器5 | 不好 | 接受 | 门票1 |
服务器6 | 不好 | 失败 | 门票2 |
预期输出:
服务器 | 合规 | 操作系统 | ref_id | com_passfail | os_passfail | 整体状态 |
---|---|---|---|---|---|---|
服务器1 | 通过 | 好的 | 通过 | 通过 | 通过 | |
服务器2 | 好 | 不好 | 通过 | 失败 | 失败 | |
服务器3 | 好的 | 有效 | 通过 | 通过 | 通过 | |
服务器4 | 失败 | 通过 | 失败 | 通过 | 失败 | |
服务器5 | 不好 | 接受 | 门票1 | 失败 | 通过 | 通过 |
服务器6 | 不好 | 失败 | 门票2 | 失败 | 失败 | 通过 |
我尝试了
CASE
表达式来实现上述规则:
SELECT *,
CASE
WHEN compliance = 'PASS' THEN 'PASS'
WHEN compliance = 'GOOD' THEN 'PASS'
WHEN compliance = 'OK' THEN 'PASS'
WHEN compliance = 'FAIL' THEN 'FAIL'
WHEN compliance = 'BAD' THEN 'FAIL'
WHEN compliance = 'NOGOOD' THEN 'FAIL'
END AS com_passfail,
CASE
WHEN os = 'PASS' THEN 'PASS'
WHEN os = 'OK' THEN 'PASS'
WHEN os = 'VALID' THEN 'PASS'
WHEN os = 'ACCEPT' THEN 'PASS'
WHEN os = 'FAIL' THEN 'FAIL'
WHEN os = 'BAD' THEN 'FAIL'
END AS os_passfail
FROM servers
我使用上述查询创建了一个视图,另一个视图从查询中选择所有内容,然后在
com_passfail
和 os_passfail
之间进行比较以确定 overall_status
值。
有没有办法在单个查询中生成上面的结果表?
除非存在未声明的极端情况,否则使用布尔逻辑而不是
CASE
表达式进行简化。SELECT *, com_pass AND os_pass OR ref_id IS NOT NULL AS overall_pass
FROM (
SELECT *
, compliance IN ('GOOD', 'OK', 'PASS') AS com_pass
, os = ANY ('{PASS,OK,VALID,ACCEPT}') AS os_pass
FROM servers
) sub;
由于 运算符优先级
,
com_pass AND os_pass OR ref_id IS NOT NULL
无需括号即可工作。
如果需要文本输出:
SELECT *, CASE WHEN com_pass AND os_pass OR ref_id IS NOT NULL
THEN 'PASS' ELSE 'FAIL' END AS overall_pass
FROM (...) sub; -- like above
准确产生您预期的结果。