提问人:Samra 提问时间:10/24/2022 最后编辑:Erwin BrandstetterSamra 更新时间:10/24/2022 访问量:128
使用 WHERE 子句中的 null 和 false 检查优化查询
Optimize query with null and false checks in WHERE clause
问:
我可以使以下查询更短和/或最佳吗?
WITH myvars (t_state, t_hv_involved, num_vehicle_hv )
AS (VALUES ('TAS', null, null))
SELECT * FROM safety.crash_summary_view c, myvars
WHERE jurisdiction = t_state
AND ((t_hv_involved::boolean = TRUE AND c.num_vehicle_hv > 0)
OR t_hv_involved is null
OR t_hv_involved::boolean = FALSE)
如果是,那么它应该过滤 .
如果为 或 ,则不进行筛选。t_hv_involved
true
num_vehicle_hv > 0
t_hv_involved
false
null
答:
1赞
Erwin Brandstetter
10/24/2022
#1
...
AND (t_hv_involved IS NOT TRUE OR c.num_vehicle_hv > 0)
假设类型应有,则无需强制转换。t_hv_involved
boolean
boolean
IS NOT TRUE
→boolean
测试布尔表达式是否生成 false 或 unknown。
→
→(而不是true IS NOT TRUE
f
NULL::boolean IS NOT TRUE
t
NULL
)
完整的测试用例可以是:
SELECT * -- you really need all columns?
FROM safety.crash_summary_view c
CROSS JOIN (
VALUES
('TAS', null::bool, null::numeric)
) v (t_state, t_hv_involved, num_vehicle_hv)
WHERE c.jurisdiction = v.t_state
AND (v.t_hv_involved IS NOT TRUE OR c.num_vehicle_hv > 0);
请注意表达式第一行中的显式类型声明。无论如何,我没有强制转换,因为默认要输入。你可能也想明确一点,并投射出来。
其他行可以是非类型化的文本,但不能用引号括起来。
看:VALUES
'TAS'
text
boolean
当然,是当你通过 时,测试不返回任何带有 的行。c.num_vehicle_hv > 0
null
null
num_vehicle_hv
v.t_hv_involved IS TRUE
评论
0赞
Laurenz Albe
10/24/2022
也许你应该推荐一个条件索引。
评论
= TRUE
t_hv_involved::boolean = FALSE
NOT t_hv_involved::boolean