【问题标题】:Ordering by varying columns in JPQL/Hibernate通过 JPQL/Hibernate 中的不同列进行排序
【发布时间】:2011-05-11 09:02:28
【问题描述】:

我有一个会话表。每个会话都有“session_start_time”和“session_end_time”。会话打开时,结束时间为空。我想获取会话列表,并按以下逻辑对其进行排序:

  1. 如果会话处于打开状态(无结束时间),则按开始时间排序。
  2. 如果会话已关闭,请按结束时间排序。

类似:

 ORDER BY (session_end_time == null) ? session_start_time : session_end_time

我使用 JPA 和 JPQL 进行查询,并使用 Hibernate 进行执行。你会推荐什么?

注意:我宁愿不将 CASE 添加到 SELECT 中,而是保持它干净,这样我就可以得到一个没有额外不需要的字段的会话列表。

【问题讨论】:

    标签: java sql hibernate jpa jpql


    【解决方案1】:

    ORDER BY nvl(session_end_time, session_start_time)

    nvl 是一个 Oracle 函数。我确信其他 DBMS 也有类似的功能

    找到这个用于休眠: 休眠中的 nvl:How to simulate NVL in HQL

    订购:https://forum.hibernate.org/viewtopic.php?f=25&t=997220&start=0

    【讨论】:

    • 这有帮助,谢谢! Coalesce 确实有效,并且比使用 CASE 更快。我需要验证它是否也适用于 JPQL(到目前为止已在 SQL 上测试过)。
    【解决方案2】:

    ORDER BY CASE 
        WHEN session_end_time IS NULL THEN session_start_time 
        ELSE session_end_time 
    END 
    

    在您的 DBMS 中工作?这不会添加字段。

    否则您可以在嵌套查询中计算它,但不要将其包含在最后的SELECT 子句中:

    SELECT field1, field2 FROM (
        SELECT field1, field2, CASE WHEN session_end_time... END AS dummyfield
    ) Q
    ORDER BY Q.dummyfield
    

    【讨论】:

    • CASE 确实适用于 PostgreSQL。似乎您的其他选项在结果集中添加了一个额外的列,我想避免这样做。与 COALESCE 相比,CASE 的执行速度较慢(无排序为 1.7ms,coalesce 为 5.61,case 为 6.89),所以我可能会选择 Coalesce。
    • 另一个选项不会添加另一列,因为SELECT 子句中未提及计算列。在这个问题中使用COALESCE 代替CASE 很好,我只是没想到...
    • 哦哦,对了,我现在明白了!这是另一种有趣的方法,但是我似乎无法在选择“*”的同时做到这一点,这是我想在 JPQL 中做的。
    猜你喜欢
    • 1970-01-01
    • 2012-01-05
    • 2019-12-22
    • 2020-02-03
    • 2020-03-27
    • 2018-10-11
    • 2011-01-26
    • 1970-01-01
    • 2011-10-28
    相关资源
    最近更新 更多