2

Mysql の Recursive SELECT クエリに関する質問はたくさんありますが、「Mysql には Recursive SELECT クエリの解決策はありません」という回答がほとんどです。

実際には特定の解決策があり、それを明確に知りたいので、この質問は、( how-to-do-the-recursive-select-query-in-mysql )で見つけることができる前の質問の続きです。

次のテーブルがあるとします。

col1 - col2 - col3
1    -  a   -  5
5    -  d   -  3
3    -  k   -  7
6    -  o   -  2
2    -  0   -  8

& col1 の値「1」に接続するすべてのリンクを見つけたい、つまり印刷したい:

1 - a - 5
5 - d - 3
3 - k - 7

次に、この単純なクエリを使用できます。

select col1, col2, @pv:=col3 as 'col3' from table1
join
(select @pv:=1)tmp
where col1=@pv

ただし、テーブルに col1 に "1" を含む 2 つのレコードと、col1 に "3" を含む 2 つのレコードがある場合は、次のようになります。

col1 - col2 - col3
1    -  a   -  5
1    -  m   -  9
5    -  d   -  3
3    -  k   -  7
6    -  o   -  2
3    -  v   -  10
2    -  0   -  8

次に、ユーザーが col1 で「1」を検索すると、2 つの「1」に接続しているすべてのリンクが表示されます。つまり、次の予想される結果が表示されます。

col1 - col2 - col3
1    -  a   -  5
1    -  m   -  9
5    -  d   -  3
3    -  k   -  7
3    -  v   -  10

それで、私の質問は、上記の予想される結果のようにすべてのリンクを表示するように、上記のクエリをどのように変更するのですか?

編集: @ゴードン、しかし、省略した場合select distinct col1, col2 from、このクエリは何かを意味します。これに取り組むことができますか( childID が増加したため、 table1 を注文できます):

select col1, col2,
         @pv:=(case when find_in_set(col3, @pv) then @pv else concat(@pv, ',', col3) 
               end) as 'col3'
  from (select * from table1 order by col1) tb1 join
      (select @pv:='1') tmp
      on find_in_set(col1, @pv) > 0

この場合、たとえばこれがデータである場合、順序は気にしません。

col1 - col2 - col3
4    -  a   -  5
1    -  d   -  2
1    -  k   -  4
2    -  o   -  3
6    -  k   -  8
8    -  o   -  9

出力は次のようになります。

col1 - col2 - col3
1    -  d   -  1,2
1    -  k   -  1,2,4
2    -  o   -  1,2,4,3

では、この結果は1,2,4,3正しいでしょうか?& col1 が にある場合は、すべてのレコードを選択します1,2,4,3。その後、最終的に期待される結果を得ることができます。

もしそうなら、私が今言った解決策を除外する特別なケースを考えてもらえますか?

4

4 に答える 4

2

このようなものがうまくいくかどうか疑問に思っています:

select distinct col1, col2
from (select col1, col2,
             @pv:=(case when find_in_set(col3, @pv) then @pv else concat(@pv, ',', col3) 
                   end) as 'col3'
      from table1 join
          (select @pv:='1') tmp
          on find_in_set(col1, @pv) > 0
     ) t

このようなものは、小さなデータセットで機能するはずです。ただし、すべての ID を文字列に入れるという考え方は、文字列の容量に制限されます。

于 2013-05-14T12:14:48.463 に答える
1

階層レベルの限られた深さでは、次のものを使用しました。

両親:

select * from mytable
join (
    select A.id Aid,B.id Bid, C.id Cid, D.id Did, E.id Eid, F.id Fid,G.id Gid, H.id Hid from mytable A
    left join mytable B on B.id=A.parent
    left join mytable C on C.id=B.parent
    left join mytable D on D.id=C.parent
    left join mytable E on E.id=D.parent
    left join mytable F on F.id=E.parent
    left join mytable G on G.id=F.parent
    left join mytable H on H.id=G.parent
    where A.id=9
) X
where id in (Aid,Bid,Cid,Did,Eid,Fid,Gid,Hid);

子供:

select * from mytable where id in (
select distinct id from mytable
join (
    select A.id Aid,B.id Bid, C.id Cid, D.id Did, E.id Eid, F.id Fid,G.id Gid, H.id Hid FROM mytable A
    left join mytable B on B.parent=A.id
    left join mytable C on C.parent=B.id
    left join mytable D on D.parent=C.id
    left join mytable E on E.parent=D.id
    left join mytable F on F.parent=E.id
    left join mytable G on G.parent=F.id
    left join mytable H on H.parent=G.id
    Where A.id=1
) X
where id in (Aid,Bid,Cid,Did,Eid,Fid,Gid,Hid)

);

于 2013-08-28T19:36:58.240 に答える
0

もっと遊びました。アイテムの順序が原因で、ユーザー変数を使用して動作させることができません。

ただし、妥当なレベルの最大数がある場合は、次のようなことができます:-

SELECT CONCAT_WS('-', a.allCols, b.allCols, c.allCols, d.allCols, e.allCols, f.allCols, g.allCols, h.allCols, i.allCols, j.allCols, k.allCols, l.allCols, m.allCols)
FROM (SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) a
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) b ON a.col3 = b.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) c ON b.col3 = c.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) d ON c.col3 = d.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) e ON d.col3 = e.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) f ON e.col3 = f.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) g ON f.col3 = g.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) h ON g.col3 = h.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) i ON h.col3 = i.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) j ON i.col3 = j.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) k ON j.col3 = k.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) l ON k.col3 = l.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) m ON l.col3 = m.col1
WHERE a.col1 = 1

これは最大 13 レベルに対応しており (OK、テスト データで使用されているのは 2 つだけです)、各列にカンマ区切りのビットが与えられ、各行はダッシュ (-) で結合されます。

于 2013-05-14T16:07:03.090 に答える