2016-05-09 5 views
1

My MYSQLデータベースは、各アイテムが任意の数の子孫を持つことができる木のようなシステムを使用します。各項目には、親を含む通常のINT '親'列と、すべての祖先のIDを含むコンマ区切りの文字列で構成されるVARCHAR 'parents'列があります。アイテムの子孫をコンマで区切られた文字列で検索するMYSQLクエリ

id parent parents 
------------------------------- 
1  0   0 
2  1   0,1 
3  1   0,1 
4  3   0,1,3 

すべてのアイテムのリストを取得する必要があります。すべてのアイテムの総数はカウントアップされています。ここで私がこれまで持っているクエリされています

SELECT items.id AS item_id, 
COUNT(children.id) AS children 
FROM items items 
LEFT JOIN items children ON (items.id IN (children.parents)) 

これはちょうど私がこれを適切に行うにはどうすればよい0の子カウントは、1行を送り返しますか?

EDIT:それはこのように表示されるようにクエリを固定した後

SELECT 
    i.id AS item_id, 
    COUNT(*) AS children 
FROM 
    items i 
LEFT JOIN 
    items c 
    ON (i.id IN (c.parents)) 
GROUP BY i.id; 

結果は、行を示しているが、それぞれが一つだけの子供を持っています。これはデータを反映していないため、おそらくIN文に何か問題があります(FIND_IN_SETは同じことをします)。

EDIT2:

ON LOCATE(i.id, c.parents) > 0 

項目1に文を変更した後の子どもの正しい数を持っている(3)が、残りの項目はすべて1子を持つように表示されます。項目2と4には0が必要で、3には1が必要です。

+1

を参照してください。 "children"はテーブルエイリアスとカラムエイリアスとして使用されます。 "times"の "items"エイリアスと同じです。これらのエイリアスはクエリをあいまいにします – Preuk

+0

あなたの 'CREATE TABLE'ステートメントといくつかのサンプルデータを投稿してください – Preuk

+2

これは本当に悪いスキーマです、私は[Nested Set Model](https://en.wikipedia.org/)を使うようにテーブルを変更します。 wiki/Nested_set_model)を作成し、直接の親カラムをバックアップとして使用します。その後、非常に簡単なクエリを実行して、子孫の数や必要な数を取得できます。 – superphonic

答えて

1

COUNT()は、意図した通りに動作させるためにはGROUP BY items.idにする必要があります。 this question又はMySQL documentationを参照して、実施例により、より複雑なCOUNT()/グループに対して

SELECT 
    i.id AS item_id, 
    COUNT(*) AS children 
FROM 
    items i 
LEFT JOIN 
    items c 
    ON FIND_IN_SET(i.id, c.parents) > 0 
WHERE c.id <> i.id 
GROUP BY i.id; 

:別名を持つ

少ない曖昧なものに変更します。 FIND_IN_SET()については、良い例hereです。

は同じエイリアスを複数回使用しないよう、最初sqlfiddle here

+0

これはやや良いですが、まだ動作していません。すべての行が1人の子供で表示されます。 – IndigoFenix

+0

ハハ! VARCHAR 'parents'カラム、カンマ区切りですね。 "find id in string"の部分の私の答えを修正しました – Preuk

+0

しかし、それほど深くはありません。トップレベルのアイテムには子孫の数が正しくありますが、それ以外のアイテムにはすべて1が残ります。 – IndigoFenix

関連する問題