PostgreSQL 在发送参数时在 where 中询问“group by”子句

Posted

技术标签:

【中文标题】PostgreSQL 在发送参数时在 where 中询问“group by”子句【英文标题】:PostgreSQL asking for 'group by' clause in where, when sending parameters 【发布时间】:2014-08-13 10:24:51 【问题描述】:

我在 PostgreSQL 中有一个简单的查询,当我在没有任何查询参数的情况下运行它时没问题:

select date_trunc('week', action_time),count(*) from event 
       group by date_trunc('week', action_time);

但如果我尝试将“周”作为这样的参数发送(在 Java 中):

PreparedStatement statement = connection.prepareStatement
    ("select date_trunc(?, action_time),count(*) from event" 
    + " group by date_trunc(?, action_time)");
statement.setString(1,"week");
statement.setString(2,"week");
statement.execute();

它会抛出以下错误:

ERROR: column "event.action_time" must appear in the GROUP BY clause or 
be used in an aggregate function

这是正常行为吗?

【问题讨论】:

【参考方案1】:

准备好查询后,无法保证您将为两个占位符绑定相同的值 ('week')。如果不这样做,查询将是非法的,这就是 postgres 不允许准备它的原因。

解决此问题的一种方法是更改​​您的查询,以便您只绑定一次'week',然后在子查询中使用它:

PreparedStatement statement = connection.prepareStatement
    ("select dt, count(*) from (select date_trunc(?, action_time) as dt " 
    + "from event) s group by dt");
statement.setString(1,"week");
statement.execute();

【讨论】:

这也是我最初的想法。看看这是否仍然产生相同的执行计划会很有趣。【参考方案2】:

我认为这应该可行,但 Postgres 可能有点挑剔。例如,以下内容不起作用:

select date_trunc(val, now())
from (select 'week' as val) t

但这确实:

select date_trunc(val, now())
from (select cast('week' as text) as val) t

您可以检查此版本是否有效:

select date_trunc(datepart, action_time), count(*)
from event cross join
     (select cast(? as text) as datepart) vars
group by date_trunc(datepart, action_time);

然后只提供一个参数。

【讨论】:

以上是关于PostgreSQL 在发送参数时在 where 中询问“group by”子句的主要内容,如果未能解决你的问题,请参考以下文章

在 PostgreSQL 函数中,是不是可以检查列值是不是与给定参数值匹配?

PostgreSQL 中的 WHERE 和 FILTER (WHERE) 有啥区别?

在 PostgreSQL 的 WHERE 子句中使用函数结果

PostgreSQL:在 WHERE 子句中搜索时列不存在

Postgresql 包含在 where 子句中

在 postgreSQL 中使用 WHERE 子句创建三个表的最有效方法是啥