【问题标题】:How can I get ordered distinct IDs with pagination?如何通过分页获得有序的不同 ID?
【发布时间】:2013-11-26 02:52:17
【问题描述】:

假设我有两个表:PersonAddress。两者都有一个数字“id”列,一个人员记录可以有多个地址(外键“Address.person_id”引用“Person.id”)。

我现在想

  • 搜索个人及其地址的条件
  • 按人员/地址属性对结果排序,并且
  • 返回不同的人员ID
  • 使用分页(对行范围的附加限制,根据页码和页面大小计算)

获取不明确的个人ID非常简单:

select p.id from person p 
left join address a on a.person_id = p.id
where p.firstname is not null
order by a.city, p.lastname, p.firstname

但现在我不能只选择distinct(p.id),因为我有一个订单,除非我也选择订单条件,否则无法应用。

如果我用select distinct(id) from (...) 包装上面的SQL-sn-p,我会得到不同的ids,但会丢失顺序(id 以任意顺序出现,可能是由于散列)

我想出了一个通用但相当不切实际的解决方案,但它不能正常工作(3 个外部选择):

select id from (
    select id, rownum as r from (
        select distinct(ID), min(rownum) from (
            select p.id from person p 
            left join address a on a.person_id = p.id
            where p.firstname is not null
            order by a.city, p.lastname, p.firstname
        )
        group by (id)
        order by min(rownum)
    )
) where r>${firstrow} and r<=${lastrow}

(占位符 ${firstrow} 和 ${lastrow} 将替换为根据页码和页面大小计算的值)

  • 有没有更好的方法来获取有序的不同 ID 分页?

  • 我正在使用 Hibernate Criteria API 实现这些搜索,我能否以某种方式将外部选择实现为 Hibernate 中的 Projection,或者创建我自己的投影实现来执行此操作?

【问题讨论】:

    标签: sql oracle hibernate pagination


    【解决方案1】:

    您基本上想按他们的最小地址对人员进行排序(不确定这对我是否有意义,但它应该只对您有意义)。这种情况你可以试试

    select person_id 
    from    (
        select a.person_id , min(a.city || p.lastname || p.firstname)
        from person p left join address a 
            on (a.person_id = p.id)
        where p.firstname is not null
        group by a.person_id
        order by 2 ) 
    where rownum < x
    

    几个技术说明 -

    • 如果每个人都有地址,请丢失left join
    • 如果您使用group by,则无需指定distinct

    【讨论】:

    • 好主意,只有在比较串联字符串时(尤其是在对日期、时间戳、数值或某些排序标准降序时)进行排序时,排序将无法正常工作。
    猜你喜欢
    • 2017-10-20
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    • 2021-06-08
    • 2016-12-09
    • 2021-01-24
    • 2023-04-04
    相关资源
    最近更新 更多