如何将 HAVING 应用于别名

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

我有一个像这样动态创建列的查询:

SELECT 
v_list_client.id AS "id",
EXISTS(
  SELECT id FROM message 
  WHERE to_phone_number = v_list_client."phoneNumber" 
    AND  created_by_agent_id != 
  (SELECT id FROM agent WHERE agent_role_id = (
    SELECT id FROM agent_role WHERE label = 'Bot'))
) AS "hasReceivedMessageFromAgent",
*
FROM v_list_client
LEFT JOIN v_form
ON (v_form."client" ->> 'id')::integer = id
WHERE (v_form."formTypeId")::integer = 1
AND (v_form."isReceived")::boolean = true
HAVING "hasReceivedMessageFromAgent" = true

我希望

HAVING
子句仅在客户端收到来自代理的消息时返回结果,即如果
hasReceivedMessageFromAgent
列为
true
.

sql postgresql having
1个回答
0
投票

HAVING
仅适用于
GROUP BY
之后。但是您也不能在
WHERE
子句中引用输出列。 (这就是让你树错树的原因。)见:

从结果中删除列

"hasReceivedMessageFromAgent"
。根据定义,它永远是真的,因此是噪音。你真的想在另一个
WHERE
子句中使用表达式作为过滤器。

我怀疑您的查询有更多问题。特别是

agent
上的子查询看起来可能会返回多行,这会引发异常。参见:

考虑重写:

SELECT *
FROM   v_list_client l
JOIN   v_form        f ON (f.client ->> 'id')::int = l.id  -- was a fake LEFT JOIN
WHERE  f."formTypeId"::int = 1  -- why the need to cast?
AND    f."isReceived"::boolean  -- why the need to cast?
AND    EXISTS (
   SELECT FROM message m
   LEFT   JOIN (agent a JOIN agent_role ar ON ar.label = 'Bot' AND ar.id = a.agent_role_id) ON a.id = m.created_by_agent_id
   WHERE  m.to_phone_number = l."phoneNumber" 
   AND    a.id IS NULL
   );

关于假货

LEFT JOIN
,请看:

"formTypeId"
应该已经是
integer
.
"isReceived"
应该已经是
boolean
.
两者的演员都是昂贵的废话。如果值始终有效,则列应该已经具有正确的数据类型。否则,演员表将失败。

旁白:如果可能的话,在 Postgres 中使用合法的、小写的、不带引号的标识符。参见:

© www.soinside.com 2019 - 2024. All rights reserved.