PostgreSQL在发送参数时要求'group by'子句

时间:2014-08-13 10:24:52

标签: sql postgresql jdbc group-by prepared-statement

我在PostgreSQL中有一个简单的查询,当我运行它时没有任何查询参数就可以了:

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

但是如果我尝试将'week'作为这样的参数发送(在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

这是正常行为吗?

2 个答案:

答案 0 :(得分:3)

我认为这应该有用,但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);

然后只提供一个参数。

答案 1 :(得分:3)

在准备查询时,并不保证您将为两个占位符绑定相同的值('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();