1

複合主キーである ID とバージョンを持つドキュメントを表すテーブルがあるとします。ドキュメントの複数のバージョンが同時にテーブルに存在する可能性があります。

create table document (id bigint not null, version int not null, 
    data varchar(255), primary key(id, version));

ビューの階層を含む別のテーブルがあります。(この例では外部キーやその他の制約を省略していますが、それらは適用されます)。

create table view (id bigint primary key, parent_id bigint);

そして、ビューを一連のドキュメントに関連付ける行を含む別のテーブル。view_doc.view_id と view_doc.doc_id に一意の制約があると仮定して、特定のドキュメントが特定のビューに複数回表示されないようにします。

create table view_doc (id bigint primary key, view_id bigint not null, 
    doc_id bigint not null, doc_version int);

論理的には、ビューにはそれが定義するすべてのドキュメント/バージョンが含まれます。子ビュー (view.parent_id が null でない) には、親のすべてのドキュメント/バージョンと、それ自体のドキュメントが含まれます。子ビューとその親で異なるバージョンのドキュメントが定義されている場合、子ビューで指定されたそのドキュメントのバージョンのみが表示されます。ドキュメントが NULL doc_version を使用して子ビューで指定されている場合、ドキュメントはその親ビューに存在する場合でも、その子ビューには存在しないと見なされます。

上記のルールで定義されているように (子ビューであるかどうかに関係なく)、view.id を指定すると、ビュー内のすべてのドキュメントとそれぞれのバージョンのリストが得られる SQL を構築したいと考えています。これが最終的に再帰クエリになる可能性があることはわかっていますが、単純化する場合は、厳密な 2 レベルの階層も受け入れます (つまり、子ビューの parent_id は常に null と見なすことができます)。

これを Oracle、DB2、および SQL Server で表現する必要があります。3 つのデータベースすべてでまったく同じクエリである必要はありませんが、それは確かに良いことです。

このクエリをすばやく実行するには、どのように記述しますか?

4

1 に答える 1

0

異なる DBMS が再帰を処理する方法はまったく異なります。これは、SQL サーバー専用の実用的なクエリであり、必ずしも高速ではありません。(クエリ ヒントを適用しない限り、SQL Server は再帰ネストを 100 レベルに制限することに注意してください):

--Flatten views
;with thisView as (
    select ID, 0 as nestingLevel, parent_ID
    from #view
    where id = @viewID
union all
    select v.ID, tv.nestingLevel + 1 as nestingevel, v.parent_ID
    from #view v
        inner join thisView tv on v.ID = tv.parent_id
),--Determine documents/versions to present
docSets as (
    select doc_ID, doc_version, ROW_NUMBER() over(partition by doc_id order by nestingLevel) as docSequence
    from #view_Doc
        inner join thisView tv on view_id = tv.ID
)--filter documents
select *
from docSets
where docSequence = 1
    and doc_version is not null;

質問の最後に速度について言及していますが、速度を達成するための最良の方法を決定するために必要な詳細を提供していません。通常、Sql Server では再帰の使用はあまり効率的ではありません。さらに、最も効率的なアプローチは DBMS によって異なる場合があります。Sql Server 2008 の場合は、HierarchyID データ型を参照してください: http://www.codeproject.com/Articles/37171/HierarchyID-Data-Type-in ​​-SQL-Server-2008

于 2012-09-18T22:40:08.920 に答える