【问题标题】:Using the DISTINCT keyword causes this error: not a SELECTed expression使用 DISTINCT 关键字会导致此错误:不是 SELECTed 表达式
【发布时间】:2013-02-22 21:39:48
【问题描述】:

我有一个看起来像这样的查询:

SELECT DISTINCT share.rooms
FROM Shares share
  left join share.rooms.buildingAdditions.buildings.buildingInfoses as bi
... //where clause omitted
ORDER BY share.rooms.floors.floorOrder, share.rooms.roomNumber,
         share.rooms.firstEffectiveAt, share.shareNumber, share.sharePercent

这会导致以下异常:

Caused by: org.hibernate.exception.SQLGrammarException: ORA-01791: not a SELECTed expression

如果我删除 DISTINCT 关键字,查询将毫无问题地运行。如果我删除 order by 子句,查询将毫无问题地运行。不幸的是,我似乎无法获得没有重复的有序结果集。

【问题讨论】:

  • 感谢@Lamak 的回复。我不清楚为什么 DISTINCT 会导致数据库忽略其他列,因为没有 DISTINCT 就不会忽略它们。但是,鉴于这很重要,我如何获得有序的、重复的免费结果集?
  • 那么您希望如何订购它们?如果您想为share.rooms 列提供重复的免费结果,那么您需要了解,由于同一房间可能对于floorOrderroomNumber 或任何其他列具有不同的值,您如何希望它们被订购?,按那些的最小值?,最大值?。
  • 我现在明白了。再次感谢。
  • 附带说明:我来这里是因为一个类似的问题,碰巧我忘记了 order by 子句中的一个 id 列(我用于调试)

标签: sql oracle hibernate oracle11g


【解决方案1】:

您正在尝试使用未计算的列对结果进行排序。如果您在那里没有DISTINCT,这不会是一个问题,但是由于您的查询基本上只按share.rooms 列分组,它如何将该结果集与其他可以具有多个值的列排序相同的share.rooms 一个?

【讨论】:

  • 有趣的是在编译时没有检测到这个错误,而只是在运行时。
  • @david-balažic:这是因为查询没有被编译。它在运行时被发送到 Oracle 服务器,然后才被解析和执行。
  • @D.Mika 我指的是在执行前编译的 PL/SQL 代码中的用法。
  • @DavidBalažic 好吧。在这种情况下,你是对的。这可以在编译时检测到。
  • 可以订购,但Oracle拒绝这样做,因为订单可以隐藏,它在另一个DBMS中工作。我讨厌它是 Oracle 错误消息如何误导/混淆
【解决方案2】:

这篇文章有点老了,但我为解决这个错误所做的一件事是包装查询,然后像这样在外面应用订单。

SELECT COL
FROM (
   SELECT DISTINCT COL, ORDER_BY_COL
   FROM TABLE
   // ADD JOINS, WHERE CLAUSES, ETC.
) 
ORDER BY ORDER_BY_COL;

希望这会有所帮助:)

【讨论】:

  • 完美解决方案!
  • 不会从两个值中选择不同的值吗?
  • @Enerccio 是的,你是对的。 db2tutorial.com/db2-basics/db2-select-distinct/….
  • @MatthewZackschewski 那么正确的解决方案是什么?因为如果两行有不同的 B 列,并且您只希望 A 列不同但按 B 排序,那么您就搞砸了,因为结果中的结果是重复的...
  • @Enerccio 我找不到一个好的 SQL 方法来重复数据删除和保留顺序。我看到很多这样做的参考资料,但只在一张桌子上。一旦你开始加入,它变得更加困难。我建议您在任何利用此功能的程序中实现逻辑,并使用哈希图或其他一些有效的内存结构来对此进行重复数据删除。对不起,不是最优的解决方案。
【解决方案3】:

在具有ORDER BY 的查询中使用DISTINCT 时,您必须选择您在ORDER BY 语句中使用的所有列:

SELECT DISTINCT share.rooms.floors.floorOrder, share.rooms.roomNumber,
         share.rooms.firstEffectiveAt, share.shareNumber, share.sharePercent
...
ORDER BY share.rooms.floors.floorOrder, share.rooms.roomNumber,
         share.rooms.firstEffectiveAt, share.shareNumber, share.sharePercent

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 2020-02-10
    • 2016-09-26
    • 2012-07-22
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    相关资源
    最近更新 更多