比较 3 个 CASE 表达式的整体值

问题描述 投票:0回答:1

我有一个 Postgres 数据库,其中有一个名为

servers
的表,其中包含以下列:

  • 合规状态
  • 操作系统版本
  • 参考 ID - 如果服务器不合规或操作系统不是最新版本。

一些合规值并不像“通过”或“失败”那样黑白分明。因此,我首先使用

com_passfail
表达式生成
CASE
,仅包含“PASS”/“FAIL”。
有些操作系统版本也不是黑白分明的。所以我只用“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
值。

有没有办法在单个查询中生成上面的结果表?

sql postgresql boolean-logic
1个回答
0
投票

除非存在未声明的极端情况,否则使用布尔逻辑而不是

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

小提琴

准确产生您预期的结果。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.