Кажется, что мое предложение sql HAVING не выполняется, когда мой `WHERE CASE WHEN` оценивается как false - PullRequest
1 голос
/ 13 апреля 2020

У меня есть утверждение, где оно работает, если я удалю свое CASE WHEN 1 != 1 условие. Я получаю обратно микросообщения с m.content = '<p>hi</p>' и теги с ARRAY['hello', 'gday'].

Мне известно, что мое предложение HAVING должно по-прежнему выполняться и возвращать микросообщения с соответствующими тегами, когда условие WHERE CASE WHEN оценивается как false IE, оно не фильтруется по m.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']

РЕДАКТИРОВАТЬ Фактический код с ruby интерполяцией строк

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']

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Если бы вы использовали case, то логарифм c был бы:

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

То есть вам нужно явно вернуть true. В противном случае выражения CASE возвращают NULL, что рассматривается в выражении WHERE как "ложное".

Однако я не рекомендую выражение CASE для этого. Instad:

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

Конечно, это можно упростить, но я предполагаю, что 1 <> 1 обусловлен заменой параметров.

0 голосов
/ 13 апреля 2020
Предложение

Where просто идет с:

where (1 != 1 and m.content = '<p>hi</p>')

Однако первое условие никогда не вернет true (1 != 1). Итак, вы можете упростить это:

where (m.content = '<p>hi</p>')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...