1

我对 JPQL 中的 DISTINCT 感到困惑。我有两个相同的 JPQL 查询,除了其中一个中的“DISTINCT”:

String getObjectsForFlow =
    "SELECT  " +
    "    se.componentID " +
    "FROM " +
    "    StatisticsEvent se " +
    "WHERE " +
    "    se.serverID IS NOT NULL " +
    "    AND se.flowID = :uuid " +
    "    AND se.componentID IS NOT NULL " +
    "ORDER BY " +
    "    se.timeStamp desc ";

String getObjectsForFlowDistinct =
    "SELECT DISTINCT " +
    "    se.componentID " +
    "FROM " +
    "    StatisticsEvent se " +
    "WHERE " +
    "    se.serverID IS NOT NULL " +
    "    AND se.flowID = :uuid " +
    "    AND se.componentID IS NOT NULL " +
    "ORDER BY " +
    "    se.timeStamp desc ";

我运行了一些代码来获取每个查询的结果并将它们转储到标准输出,并且我得到了很多行,其中一些重复的非重复,但对于不同的我只得到一个行,它是非重复列表的一部分。

NOT DISTINCT
::: 01e2e915-35c1-6cf0-9d0e-14109fdb7235
::: 01e2e915-35c1-6cf0-9d0e-14109fdb7235
::: 01e2e915-35d9-afe0-9d0e-14109fdb7235
::: 01e2e915-35d9-afe0-9d0e-14109fdb7235
::: 01e2e915-35bd-c370-9d0e-14109fdb7235
::: 01e2e915-35bd-c370-9d0e-14109fdb7235
::: 01e2e915-35aa-1460-9d0e-14109fdb7235
::: 01e2e915-35d1-2460-9d0e-14109fdb7235
::: 01e2e915-35e1-7810-9d0e-14109fdb7235
::: 01e2e915-35e1-7810-9d0e-14109fdb7235
::: 01e2e915-35d0-12f0-9d0e-14109fdb7235
::: 01e2e915-35b0-cb20-9d0e-14109fdb7235
::: 01e2e915-35a8-66b0-9d0e-14109fdb7235
::: 01e2e915-35a8-66b0-9d0e-14109fdb7235
::: 01e2e915-35e2-6270-9d0e-14109fdb7235
::: 01e2e915-357f-33d0-9d0e-14109fdb7235
DISTINCT
::: 01e2e915-35e2-6270-9d0e-14109fdb7235

其他条目在哪里?我希望一个包含十一个(我认为)条目的 DISTINCT 列表。

4

4 回答 4

0

Double check equals() method on your StatisticsEvent entity class. Maybe those semantically different values returns same when equals() is called hence producing this behavior

于 2013-07-10T06:20:56.907 回答
0

问题是“ORDER BY se.timeStamp”子句。为了满足请求,JPQL 将 ORDER BY 字段添加到 SELECT DISTINCT 子句。

这就像 JPQL 和 SQL 之间相互作用的边界案例。JPQL 语法清楚地将 DISTINCT 修饰符仅应用于 se.componentID,但是当翻译成 SQL 时,会插入 ORDER BY 字段。

我很惊讶 ORDER BY 字段必须被选中。一些数据库可以返回由不在 SELECTion 中的字段排序的数据集。甲骨文可以这样做。我的基础数据库是 Derby ——这可能是 Derby 的限制吗?

于 2013-07-10T21:50:15.070 回答
0

这两个查询都是不正确的 JPQL 查询,因为 ORDER BY 子句引用了不在选择列表中的项目。JPA 2.0 规范包含与这种情况匹配的示例:

以下两个查询是不合法的,因为 orderby_item 没有反映在查询的 SELECT 子句中。

SELECT p.product_name FROM Order o JOIN o.lineItems l JOIN l.product p JOIN o.customer c
WHERE c.lastname = 'Smith' AND c.firstname = 'John'<br> ORDER BY p.price

SELECT p.product_name
FROM Order o, IN(o.lineItems) l JOIN o.customer c
WHERE c.lastname = 'Smith' AND c.firstname = 'John' ORDER BY o.quantity

当然,如果实现可以给出明确的错误消息而不是试图猜测错误查询的预期结果会更好。

于 2013-07-15T20:15:47.250 回答
0

Oracle 不支持带有 order by 的 SELECT DISTINCT,除非 order by 列在 SELECT 中。不确定是否有任何数据库。如果不需要 DISTINCT(因为行是唯一的,所以不会运行),它将在 Oracle 中工作,但如果需要运行,您将收到错误消息。

你会得到,“ORA-01791: not a SELECTed expression”

如果您使用的是 EclipseLink,则此功能由 DatabasPlatform 方法控制,

shouldSelectDistinctIncludeOrderBy()

如果您的数据库不需要,您可以扩展您的平台以返回 false。

不过,我看不到添加 TIMESTAMP 会如何改变查询结果?

于 2013-07-11T13:17:28.073 回答