2017-09-08 6 views
0

バージョン管理をサポートし、データの重複を減らすために、次の表構造を使用しました(一部の列を削除してスタブを作成しました)。記事のレビュープロセスを想像してみてください。各ステップはデータベース(article_meta)に保存されています。記事自体が変更されるたびに、データはDBにも格納されます。 バージョン管理は、先行者(pre_meta_id)への参照によって行われます。DB2:間接参照データの結合方法

WITH 
    t_article_meta (id, pre_meta_id, user_id, state) as (
     values   (1, NULL, 101, 'submitted') 
     union all values (2, 1, 7, 'inreview') 
     union all values (3, 2, 7, 'rejected') 
     union all values (4, 3, 101, 'submitted') 
     union all values (5, NULL, 202, 'submitted') 
     union all values (6, 5, 7, 'inreview') 
     union all values (7, 6, 7, 'accepted') 
     union all values (8, 4, 7, 'inreview') 
     union all values (9, 8, 7, 'accepted') 
    ), 
    t_article (id, meta_id, content) as (
     values   (1, 1, 'Hello wordl') 
     union all values (2, 4, 'Hello world') 
     union all values (3, 5, 'Lorem ipsum doloret') 
    ) 
SELECT ...; 

は、今私は(前任者を経由して間接的にのみ)は直接の言及がなくても何とかメタデータや商品データを組み合わせたビューを作成したいです。

id | pre_meta_id | user_id | state  | content (left join) | content (I want to have)    
---|-------------|---------|-----------|---------------------|------------------------- 
1 | NULL  | 101  | submitted | Hello wordl   | Hello wordl   
2 | 1   | 7  | inreview | NULL    | Hello wordl   
3 | 2   | 7  | rejected | NULL    | Hello wordl   
4 | 3   | 101  | submitted | Hello world   | Hello world   
5 | NULL  | 202  | submitted | Lorem ipsum doloret | Lorem ipsum doloret 
6 | 5   | 7  | inreview | NULL    | Lorem ipsum doloret 
7 | 6   | 7  | accepted | NULL    | Lorem ipsum doloret 
8 | 4   | 7  | inreview | NULL    | Hello world   
9 | 8   | 7  | accepted | NULL    | Hello world    

DB2のようなものを実現するにはどうしたらいいですか?私の最初のアイデア:機能に関する参加(記事に関連する先行者を取得する)は、本当に私にとっては高価なものです。このSQLは、仕事をするだろう

答えて

1

SELECT m.id, successor_id, user_id, state, content, 
     last_value(content,'IGNORE NULLS') over (order by m.id) as last_value 
    FROM article_meta m 
    LEFT JOIN article a 
     ON m.id = a.article_meta_id 
ORDER BY m.id 

それは(違いを示すためにあなたの期待した結果に比べて別の名前で)aditional列を持つテーブルを結合するために参加規則的である あなたがしたい場合がありますその列の名前を変更して内容を削除し、期待通りの結果を得ることができます。

with temp (id, pre_meta_id, user_id, state, level, parent, root) as (
select m.id, m.pre_meta_id, m.user_id, m.state, 1 as level, m.pre_meta_id as parent, m.id as root 
from article_meta m, article a 
where m.id = a.meta_id 
union all 
select m.id, m.pre_meta_id, m.user_id, m.state, level + 1 as level, t.id as parent, t.root 
from temp t, article_meta m 
where m.pre_meta_id = t.id 
    and m.id not in (select meta_id from article) 
    and level < 10 
) 
select * 
    from temp t 
    left join article a 
    on t.root = a.meta_id 
order by 1 
+0

をそれは限り動作します。それはこのようになります - 私たちはすべてのお子様のためのタイトル/コンテンツを取得するために再帰クエリを定義するために持っているようにSQLが複雑になり、調整要件について

idとsuccessor_idのシーケンス(実際には先行者ID ...)は同期しています。この問題を示すために例を更新しました。 – Mrks83

+0

@ MRKS83あなたの新しい要件を満たす調整済みのソリューションをチェックしてください – MichaelTiefenbacher

関連する問題