2016-09-08 18 views
8

Ectoで実行する予定のクエリで再帰CTEの結果を使用するにはどうすればよいですか?Ectoでの再帰CTEの使用

-- nodes table example -- 

id parent_id 
1 NULL 
2 1 
3 1 
4 1 
5 2 
6 2 
7 3 
8 5 

と私もそうように構成された別のテーブルのnodes_usersを持っている:

-- nodes_users table example -- 

node_id user_id 
1   1 
2   2 
3   3 
5   4 

、私が持つすべてのユーザーをつかむしたいたとえばのは、私がそうように構成されたテーブル、ノードを、持っているとしましょうで、または特定のノード上のノードは、例のためのノードを選択してみましょうwのID/8

私がそうするように、次の再帰 のクエリを使用することができ

WITH RECURSIVE nodes_tree AS (
    SELECT * 
    FROM nodes 
    WHERE nodes.id = 8 
UNION ALL 
    SELECT n.* 
    FROM nodes n 
    INNER JOIN nodes_tree nt ON nt.parent_id = n.id 
) 
SELECT u.* FROM users u 
INNER JOIN users_nodes un ON un.user_id = u.id 
INNER JOIN nodes_tree nt ON nt.id = un.node_id 

これは、ユーザーのw/IDの1、2のために*。ユーザーを返す必要があり、そして4

は、私が理想戻ってくるようにし、エクトを使用して、この同じクエリを実行できるかどうかはわかりません連鎖可能な出力フラグメントマクロを使用して未加工のSQLをクエリに挿入できることは理解していますが、どこにこのマクロが使用されるのか、それが最も適切なルートであるかどうかはわかりません。

ヘルプや提案をいただければ幸いです。

答えて

11

フラグメントを使用してこれを達成できました。ここで私が使用したコードの例です。私はおそらく、このメソッドをストアドプロシージャに移動します。

Repo.all(MyProj.User, 
    from u in MyProj.User, 
    join: un in MyProj.UserNode, on: u.id == un.user_id, 
    join: nt in fragment(""" 
    (
    WITH RECURSIVE node_tree AS (
     SELECT * 
     FROM nodes 
     WHERE nodes.id = ? 
    UNION ALL 
     SELECT n.* 
     FROM nodes n 
     INNER JOIN node_tree nt ON nt.parent_id == n.id 
    ) 
) SELECT * FROM node_tree 
    """, ^node_id), on: un.node_id == nt.id 
)