首页 > 解决方案 > 当我的“WHERE CASE WHEN”评估为假时,我的 sql HAVING 子句似乎没有运行

问题描述

如果我删除我的CASE WHEN 1 != 1条件,我有一个有效的声明。我收到了微博m.content = '<p>hi</p>'和其中的标签ARRAY['hello', 'gday']

我的知识是,当条件评估为未过滤的 IE时,我的HAVING子句仍应运行并返回带有匹配标签的微博,并返回具有与之关联的标签的微博。WHERE CASE WHENfalsem.content = '<p>hi</p>'ARRAY['hello', 'gday']

但情况并非如此,当我的WHERE条件没有运行时,因为CASE条件评估为false它似乎HAVING也没有运行,并且我返回 0 结果。这是预期的行为吗?如果是,为什么?

SELECT m.* 
FROM microposts AS m 
JOIN taggings tt ON m.id = tt.taggable_id 
JOIN tags t ON t.id = tt.tag_id 
WHERE CASE WHEN 1 != 1 THEN m.content = '<p>hi</p>' END\
GROUP BY m.id 
HAVING ARRAY_AGG(t.name ORDER BY t.name)::text[] @> ARRAY['hello', 'gday']

编辑带有红宝石字符串插值的实际代码

SELECT m.* 
FROM microposts AS m 
JOIN taggings tt ON m.id = tt.taggable_id 
JOIN tags t ON t.id = tt.tag_id 
WHERE CASE WHEN #{my_string} != '' THEN m.content = #{my_string} END
GROUP BY m.id 
HAVING ARRAY_AGG(t.name ORDER BY t.name)::text[] @> ARRAY['hello', 'gday']

标签: sqlpostgresql

解决方案


如果您要使用case,那么逻辑将是:

WHERE CASE WHEN 1 != 1 THEN m.content = '<p>hi</p>' ELSE true END

也就是说,您需要显式返回true. 否则CASE表达式返回,在子句NULL中被视为“假” 。WHERE

但是,我不建议CASE为此使用表达式。因斯塔德:

WHERE (1 <> 1 AND m.content = '<p>hi</p>') OR
      (1 = 1)

当然,这可以简化,但我假设这1 <> 1是由于参数替换。


推荐阅读