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

MySQLの幅優先探索クエリ?

    手順0:すべての隣接ペアを表示するビューを作成します

    CREATE VIEW neighbour AS
    ( SELECT loc1.id AS a
           , loc2.id AS b
      FROM locations loc1
         , locations loc2
      WHERE FIND_IN_SET(loc1.id, loc2.neighbours)>0
         OR FIND_IN_SET(loc2.id, loc1.neighbours)>0
    ) ;
    

    ステップ1:深さ1の隣人を見つける

    SELECT b AS depth1
    FROM neighbour
    WHERE a = 1;               <-- for root with id=1
    

    ステップ2:深さ2の隣人を見つける

    SELECT DISTINCT d2.b AS depth2
    FROM neighbour d1
      JOIN neighbour d2
        ON d1.b = d2.a
          AND d2.b != 1
    WHERE d1.a = 1                <-- for root with id=1
      AND d2.b NOT IN
         ( SELECT b AS depth1     <- depth1 subquery
           FROM neighbour
           WHERE a = 1            <-- for root with id=1
          )
    ;
    

    ステップ3:深さ3の隣人を見つける

    SELECT d3.b as depth3
    FROM neighbour d1
      JOIN neighbour d2
        ON d1.b = d2.a
        AND d2.b != 1
        AND d2.b NOT IN
           ( SELECT b as depth1
             FROM neighbour
             WHERE a = 1
           )
      JOIN neighbour d3
        ON d2.b = d3.a
        AND d3.b != 1
    WHERE d1.a = 1
      AND d3.b NOT IN
         ( SELECT b as depth1
           FROM neighbour
           WHERE a = 1
          )
      AND d3.b NOT IN
         ( SELECT d2.b AS depth2
           FROM neighbour d1
             JOIN neighbour d2
               ON d1.b = d2.a
               AND d2.b != 1
           WHERE d1.a = 1
             AND d2.b NOT IN
                ( SELECT b AS depth1
                  FROM neighbour
                  WHERE a = 1
                )
         )
    ;
    

    ご覧のとおり、クエリ行数の増加は指数関数的であるため、レベル4は試しません。



    1. LocalDateTime、ZonedDateTime、およびTimestamp

    2. mysqlルートパスワードをリセットする方法は?

    3. エラー値が存在しません-postgresqlINSERTINTOの問題

    4. PostgreSQLのセキュリティ監査の自動化