-1

と の 2 つのテーブルがあるPersonとしAddressます。両方とも数値列 ' ' を持ち、個人レコードには複数のアドレス (' ' を参照するid外部キー ' ' ) を含めることができます。Address.person_idPerson.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)、注文条件も選択しない限り適用できない注文があるため、今は を選択することはできません。

上記の SQL スニペットを でラップするとselect distinct(id) from (...)、個別idの s が取得されますが、順序が失われます(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か、これを行う独自の投影実装を作成できますか?

4

1 に答える 1

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
于 2013-11-13T13:29:43.050 に答える