PostgreSQL 查询在 pgAdmin 中有效,但在 Java EclipseLink 中无效
PostgreSQL query works in pgAdmin but not in Java EclipseLink
我有一个 SQL 计算每个截断日期(月、日、小时)的行数。想想历史图表。如果在 pgAdmin 中执行,查询工作正常,但在 Java 中使用 EclipseLink 失败。
pgAdmin 查询:
SELECT date_trunc( 'hour', delivered_at ),
COUNT(date_trunc( 'hour', delivered_at )) AS num
FROM messages
WHERE channel_type='EMAIL'
AND created_at>='2016-02-28 16:01:08.882'
AND created_at<='2016-02-29 16:01:08.882'
GROUP BY date_trunc( 'hour', delivered_at );
JPQL 命名查询
SELECT FUNCTION('date_trunc', 'hour', m.deliveredAt ),
COUNT(FUNCTION('date_trunc', 'hour', m.deliveredAt )) AS num
FROM Message m
WHERE m.channelType = :channelType
AND m.createdAt >= :fromDate
AND m.createdAt <= :toDate
GROUP BY FUNCTION('date_trunc', 'hour', m.deliveredAt )
EclipseLink 调试日志:
SELECT date_trunc(?, delivered_at), COUNT(date_trunc(?, delivered_at)) FROM messages
WHERE (((channel_type = ?) AND (created_at >= ?)) AND (created_at <= ?)) GROUP BY date_trunc(?, delivered_at)
bind => [hour, hour, EMAIL, 2015-12-27 00:00:00.0, 2015-12-27 00:00:00.0, hour]
错误:
ERROR: column "messages.delivered_at" must appear in the GROUP BY
clause or be used in an aggregate function Position: 23
PostgreSQL 日志:
2016-03-01 13:22:08 CET ERROR: column "messages.delivered_at" must
appear in the GROUP BY clause or be used in an aggregate function at
character 23 2016-03-01 13:22:08 CET STATEMENT: SELECT date_trunc(,
delivered_at), COUNT(delivered_at) FROM messages WHERE (((channel_type
= ) AND (created_at >= )) AND (created_at <= )) GROUP BY date_trunc(, delivered_at) 2016-03-01 13:22:08 CET LOG: execute
S_2: SELECT 1
如果我从 EclipseLink 记录的查询中替换绑定变量并在 pgAdmin 中执行它,则查询有效。这是怎么回事?
编辑:澄清一下,它也适用于 em.createNativeQuery。
在 postgresql 上,您可以使用以下语法
GROUP BY 1
这意味着您将使用 SELECT 子句中第一个选定的属性对聚合进行分组。这可能对您有帮助
PostgreSQL 可以有 trouble 解析参数绑定,在这种情况下表现为本机 SQL 参数内联工作,而 JPA 生成 SQL 默认值绑定参数失败。
一个解决方案是关闭参数绑定,方法是将 "eclipselink.jdbc.bind-parameters" 的值 "false" 作为特定查询的查询提示,或作为持久性单元 属性 传递给默认关闭所有查询的参数绑定。
我有一个 SQL 计算每个截断日期(月、日、小时)的行数。想想历史图表。如果在 pgAdmin 中执行,查询工作正常,但在 Java 中使用 EclipseLink 失败。
pgAdmin 查询:
SELECT date_trunc( 'hour', delivered_at ),
COUNT(date_trunc( 'hour', delivered_at )) AS num
FROM messages
WHERE channel_type='EMAIL'
AND created_at>='2016-02-28 16:01:08.882'
AND created_at<='2016-02-29 16:01:08.882'
GROUP BY date_trunc( 'hour', delivered_at );
JPQL 命名查询
SELECT FUNCTION('date_trunc', 'hour', m.deliveredAt ),
COUNT(FUNCTION('date_trunc', 'hour', m.deliveredAt )) AS num
FROM Message m
WHERE m.channelType = :channelType
AND m.createdAt >= :fromDate
AND m.createdAt <= :toDate
GROUP BY FUNCTION('date_trunc', 'hour', m.deliveredAt )
EclipseLink 调试日志:
SELECT date_trunc(?, delivered_at), COUNT(date_trunc(?, delivered_at)) FROM messages
WHERE (((channel_type = ?) AND (created_at >= ?)) AND (created_at <= ?)) GROUP BY date_trunc(?, delivered_at)
bind => [hour, hour, EMAIL, 2015-12-27 00:00:00.0, 2015-12-27 00:00:00.0, hour]
错误:
ERROR: column "messages.delivered_at" must appear in the GROUP BY clause or be used in an aggregate function Position: 23
PostgreSQL 日志:
2016-03-01 13:22:08 CET ERROR: column "messages.delivered_at" must appear in the GROUP BY clause or be used in an aggregate function at character 23 2016-03-01 13:22:08 CET STATEMENT: SELECT date_trunc(, delivered_at), COUNT(delivered_at) FROM messages WHERE (((channel_type = ) AND (created_at >= )) AND (created_at <= )) GROUP BY date_trunc(, delivered_at) 2016-03-01 13:22:08 CET LOG: execute S_2: SELECT 1
如果我从 EclipseLink 记录的查询中替换绑定变量并在 pgAdmin 中执行它,则查询有效。这是怎么回事?
编辑:澄清一下,它也适用于 em.createNativeQuery。
在 postgresql 上,您可以使用以下语法
GROUP BY 1
这意味着您将使用 SELECT 子句中第一个选定的属性对聚合进行分组。这可能对您有帮助
PostgreSQL 可以有 trouble 解析参数绑定,在这种情况下表现为本机 SQL 参数内联工作,而 JPA 生成 SQL 默认值绑定参数失败。
一个解决方案是关闭参数绑定,方法是将 "eclipselink.jdbc.bind-parameters" 的值 "false" 作为特定查询的查询提示,或作为持久性单元 属性 传递给默认关闭所有查询的参数绑定。