2016-12-17 3 views
1

私のようなセットの中に一連の番号を定義するMySQLのDBを持っている:直列接続を定義する2つの列を持つMySQL DB内の一連の数値を連鎖する方法は?

set item1 item2 
1  1  2 
1  2  3 
1  3  4 
1  4  5 
1  5  6 

私は、クエリ(またはクエリ)を書きたい1を設定することがまたがる一連の数字である私に返しますこれは可能ですか?

私が扱っている実際のDBには何百ものセットが含まれていることに注意してください。また、各セットには一連のアイテムが含まれていることもあります(1セットあたり50アイテムまでです)。また、私は完全にはわかりませんが、DBには一連の数値が分割されるケースもあります。上記の例を使用して、次のような事例があるかもしれません:[1, 2, 3, 4, 5, 6][1, 2, 3, 7, 8, 9]

set item1 item2 
1  1  2 
1  2  3 
1  3  4 
1  4  5 
1  5  6 
1  3  7 
1  7  8 
1  8  9 

その場合、私はそのセット1は、数字の2つのシリーズを持っているかを知りたいと思います。これはうまくいけば1つのクエリ(または必要な場合は複数のクエリ)で可能ですか?


編集:私は理解し、質問を容易にするために順番に番号1-9を使用しますのでご注意ください。実際のデータは、はるかに混在しており、順序どおりではありません。

+0

2番目の問題は、最初のものを超える難易度です。 7,8がA系列かB系列かを知る方法はありません。(私はシリーズBの論理も理解していません) – Strawberry

+0

2つの系列は3で分割されています。それは道路の分岐点のように考えてください。私はデータセットが与えられればそれは理にかなっていると思うが、私は単なる(あるいは多分)複数のMySQLコールを扱うのは不可能かもしれないことを認めている。私はPHPなどを取得する必要がありますこれに関わっている。 – HartleySan

+0

実際の問題は、明らかに2番目の問題よりも複雑であるため、私たちが何を提供できるのかは分かりません。 – Strawberry

答えて

1

ご承知のとおりのオプションが含まれて、MySQLは、「アウト・オブ・ボックス」再帰を扱うことができません。

  1. がに隣接リストからの切り替えストアドプロシージャ
  2. を書きます代替モデル(例:同じ頻度(アプリケーションレベルのコードに再帰を処理
  3. 必要とすることができるようにそれ自体にテーブルを結合するネストされたセット)
  4. は、例えば、PHPのビット)ここ

オプション3を使用した例であるが、それオプション4に合わせて簡単に調整することができます...

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table 
(
    family_id INT NOT NULL, 
    item_id INT NOT NULL, 
    parent_id INT NULL, 

    PRIMARY KEY(family_id, item_id) 
); 

INSERT INTO my_table 
VALUES (101, 1, null), (101, 2, 1), (101, 3, 2), (101, 4, 3), 
     (101, 5, 4), (101, 6, 5), (101, 7, 3), (101, 8, 7), (101, 9, 8); 

SELECT CONCAT_WS(',' 
    , a.item_id 
    , b.item_id 
    , c.item_id 
    , d.item_id 
    , e.item_id 
    , f.item_id 
    , g.item_id 
    , h.item_id 
    , i.item_id 
    ) series 
FROM 
    my_table a 
LEFT JOIN 
    my_table b ON b.parent_id = a.item_id AND b.family_id = a.family_id 
LEFT JOIN 
    my_table c ON c.parent_id = b.item_id AND c.family_id = b.family_id 
LEFT JOIN 
    my_table d ON d.parent_id = c.item_id AND d.family_id = c.family_id 
LEFT JOIN 
    my_table e ON e.parent_id = d.item_id AND e.family_id = d.family_id 
LEFT JOIN 
    my_table f ON f.parent_id = e.item_id AND f.family_id = e.family_id 
LEFT JOIN 
    my_table g ON g.parent_id = f.item_id AND g.family_id = f.family_id 
LEFT JOIN 
    my_table h ON h.parent_id = g.item_id AND h.family_id = g.family_id 
LEFT JOIN 
    my_table i ON i.parent_id = h.item_id AND i.family_id = h.family_id 
WHERE 
    a.parent_id IS NULL; 

    +-------------+ 
    | series  | 
    +-------------+ 
    | 1,2,3,4,5,6 | 
    | 1,2,3,7,8,9 | 
    +-------------+ 
+0

お返事ありがとうございますが、オプション#1と#2について質問があります:ストアドプロシージャを呼び出すと、どのように役立ちますか?再帰的に呼び出すことができるからですか?また、#2を構造化する方法の簡単な例を教えてください。そして、はい、記録のために、私はオプション#4を使用して問題を解決しました。しかし、#1と#2についてはまだ興味があります。ありがとう。 – HartleySan

+0

1. http://stackoverflow.com/questions/33750165/stored-procedure-with-recursive-call-using-mysqlを参照してください。 2.については、明確なガイドを参照してください:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ – Strawberry

+0

素晴らしいリンク。ありがとう。 #1は実際にはSPとの再帰呼び出しであり、#2は 'parent_id'フィールドで多くの意味を持ちます。前にも同様のことをやったことがありますが、この場合#2はあまり意味がありません。それでも、非常に知って良い。ありがとう。 – HartleySan

0

私は最初の問題を解決できます。

create table test 
(
    sset int not null 
    , item1 int not null 
    , item2 int not null 
) engine=InnoDB; 

insert into test 
values 
(1, 1, 2) 
, (1, 2, 3) 
, (1, 3, 4) 
, (1, 4, 5) 
, (1, 5, 6) 
:「設定」がキーワードですので、私はあなたがテーブルを作成し、データを挿入 http://sqlfiddle.com/#!9/ef6360/5

で結果を見ることができる「SSET」

への最初の列を名前を変更することを

注意

クエリを実行:

select 
    sset 
    , group_concat(distinct item1or2 order by item1or2 asc) 
from 
    (
     select 
      sset 
      , item1 as item1or2 
     from test 
     union all 
     select 
      sset 
      , item2 as item1or2 
     from test 
    ) u; 

出力は次のとおりです。

1,2,3,4,5,6 
+0

「ORDER BY ASC」句を使用するときに、数字が常に正しい順序である場合にのみ機能します。残念ながら、それは私が扱っている実際のデータセットの場合に必ずしも当てはまるとは限りません。私は最初に私の元のポストでそれを言及しないことをお詫び申し上げます。私は質問をより簡単でより一般的にするために列名 'set'と連続番号を使用しましたが、残念ながらデータの現実ではありません。私はそれを反映するために私の質問を編集します。ごめんなさい。 – HartleySan

関連する問題