如何通过分页获得有序的不同ID?

时间:2013-11-13 13:19:32

标签: sql oracle hibernate pagination

假设我有两个表: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-snippet,我会得到不同的id,但会丢失订单(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,或者创建我自己的投影实现吗?此

1 个答案:

答案 0 :(得分: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