sql >> データベース >  >> RDS >> PostgreSQL

無向グラフ全体をトラバースし、見つかったすべてのエッジを返すためのPostgreSQLSQLクエリ

    私はこれに到達しました、それはどんな種類のデータでも無限ループに入るべきではありません:

    --create temp table edges ("from" text, "to" text);
    --insert into edges values ('initial_node', 'a'), ('a', 'b'), ('a', 'c'), ('c', 'd');
    
    with recursive graph(points) as (
      select array(select distinct "to" from edges where "from" = 'initial_node')
      union all
      select g.points || e1.p || e2.p
      from graph g
      left join lateral (
        select array(
          select distinct "to"
          from edges 
          where "from" =any(g.points) and "to" <>all(g.points) and "to" <> 'initial_node') AS p) e1 on (true)
      left join lateral (
        select array(
          select distinct "from"
          from edges 
          where "to" =any(g.points) and "from" <>all(g.points) and "from" <> 'initial_node') AS p) e2 on (true)
      where e1.p <> '{}' OR e2.p <> '{}'
      )
    select distinct unnest(points)
    from graph
    order by 1
    

    再帰クエリは、選択できるものに関して非常に制限されており、副選択内で再帰結果を使用できないため、NOT IN(select * from recursive where ...)を使用することはできません。 LEFT JOIN LATERALを使用し、=ANY()と<> ALL()を使用して結果を配列に格納すると、この難問が解決されました。




    1. 同じレコードを保存するListArray

    2. MySQLで再帰的なSELECTクエリを実行するにはどうすればよいですか?

    3. ハロウィーンの問題–パート2

    4. Railsの移行テーブルの主キーを作成