2017-04-26 1 views
0

これは非常に奇妙なクエリであり、どのように進めるのかわかりません。 以下はその表です。以下のテーブルのpostgresクエリを書くには?

id descendentId attr_type attr_value 
1 {4}    type_a  
2 {5}    type_a  
3 {6}    type_a  
4 {7,8}    type_b  
5 {9,10}   type_b  
6 {11,12}   type_b  
7 {}    type_x TRUE 
8 {}    type_y "ABC" 
9 {}    type_x FALSE 
10 {}    type_y "PQR" 
11 {}    type_x FALSE 
12 {}    type_y "XYZ" 

クエリの入力、出力が"ABC"する必要があります。.. 1,2,3になります。

ロジックは〜1,2,3からattr_type xに達するまで子孫をループします。 attr_type x(7,9,11)に達した場合は、どちらがtrueかを確認してください。例えば、 7が真の場合は 8type_y(チェック行4)の兄弟を取得し、値を返します。

すべてこれは文字列形式です。

+0

'descendentId'のデータ型は何ですか? –

+0

代わりに 'parentId'を格納すれば、これははるかに簡単になります(そういう意味では、自己参照の外部キーを使うことさえできます)。 – pozs

答えて

0

これはrecursive CTEsで解決することができます。

with recursive params(id) as (
    select e::int 
    from unnest(string_to_array('1,2,3', ',')) e -- input parameter 
), 
rcte as (
    select '{}'::int[] parents, 
      id, 
      descendent_id, 
      attr_type, 
      attr_value 
    from attrs 
    join params using (id) 
    union all 
    select  parents || rcte.id, 
       attrs.id, 
       attrs.descendent_id, 
       attrs.attr_type, 
       attrs.attr_value 
    from  rcte 
    cross join unnest(descendent_id) d 
    join  attrs on attrs.id = d 
    where  d <> all (parents) -- stop at loops in hierarchy 
) 
select y.attr_value 
from rcte x 
join rcte y using (parents) -- join siblings 
where x.attr_type = 'type_x' 
and x.attr_value = 'true' 
and y.attr_type = 'type_y' 

http://rextester.com/YDLDH11322

+0

素晴らしい私はそれを試してあなたに知らせます。 – user1298426

1

これは本当に、そのようなクエリの複雑なデータモデルですが、私の方法は、階層最初に平らにある:

WITH RECURSIVE 
    typex(id, use) AS (
     SELECT id, attr_value::boolean 
     FROM weird 
     WHERE attr_type = 'type_x' 
     UNION 
     SELECT w.id, typex.use 
     FROM weird w 
      JOIN typex 
       ON ARRAY[typex.id] <@ w.descendentid 
    ), 
    typey(id, value) AS (
     SELECT id, attr_value 
     FROM weird 
     WHERE attr_type = 'type_y' 
     UNION 
     SELECT w.id, typey.value 
     FROM weird w 
      JOIN typey 
       ON ARRAY[typey.id] <@ w.descendentid 
    ) 
SELECT id, value 
FROM typex 
    NATURAL JOIN typey 
WHERE use 
    AND id = 1; 

┌────┬───────┐ 
│ id │ value │ 
├────┼───────┤ 
│ 1 │ ABC │ 
└────┴───────┘ 
(1 row) 
+0

あなたは明示的にWHERE use AND id = 1を挙げました。したがって、9が真で7が偽ならば、何も返されません。また、入力を受け付けず、完全な表で実行します。 – user1298426

+0

私はそのコメントを理解できませんが、あなたが他の答えを受け入れたので、私はあなたの問題が解決されたと思います。 –

関連する問題