2009-07-01 24 views
52

あらかじめありがとうございます。複数の子行を1つの行に結合するMYSQL

私は出力に探していますどのような二つのテーブル

Ordered_Item

ID | Item_Name 
1 | Pizza 
2 | Stromboli

Ordered_Options

Ordered_Item_ID | Option_Number | Value 
     1    43   Pepperoni 
     1    44   Extra Cheese 
     2    44   Extra Cheese

を持っているが、MySQLのクエリでこの効果

に何かあります

私はほとんどの構文エラーで終わる多数のオプションを試してみましたが、出力

ID | Item_Name | Option_1 | Option_2 
1 Pizza  Pepperoni Extra Cheese 
2 Stromboli  NULL  Extra Cheese

は、私がGROUP_CONCATを試してみましたが、私は探しています本当にないのthatsています。私は以下のような原始的な例を持っています。私はオプションが毎回同じ順序である必要があります。また、情報が収集されるプログラムでは、確実に起こることを確実にする方法がありません。オプション番号に従ってそれらを連結することは可能ですか?また、私は静的なソリ​​ューションが動作するので、私は決して5つ以上のオプションがあることを知っている

Select Ordered_Items.ID, 
    Ordered_Items.Item_Name, 
FROM Ordered_Items 
    JOIN (SELECT Ordered_Options.Value FROM Ordered_Options Where Option_Number = 43) as Option_1 
     ON Ordered_Options.Ordered_Item_ID = Ordered_Item.ID 
    JOIN (SELECT Ordered_Options.Value FROM Ordered_Options Where Option_Number = 44) as Option_2 
     ON Ordered_Options.Ordered_Item_ID = Ordered_Item.ID; 

ありがとう! ジョー

答えて

90

ここGROUP_CONCATグループ機能を利用することになり、最も簡単な方法..

出力しまう
select 
    ordered_item.id as `Id`, 
    ordered_item.Item_Name as `ItemName`, 
    GROUP_CONCAT(Ordered_Options.Value) as `Options` 
from 
    ordered_item, 
    ordered_options 
where 
    ordered_item.id=ordered_options.ordered_item_id 
group by 
    ordered_item.id 

Id    ItemName  Options 

1    Pizza   Pepperoni,Extra Cheese 

2    Stromboli  Extra Cheese 

あなたはできるだけ多くの選択肢を持つことができる方法クエリを変更する必要はありません。

ああ、あなたの結果はクロップ取得を参照してください場合は、あなたがこのようなGROUP_CONCATのサイズ制限を増やすことができます:ピボットと呼ばれ、それが直接のMySQLでサポートされていない

SET SESSION group_concat_max_len = 8192; 
+3

彼は「私はgroup_concatを試みたが、実際には私が探しているものではない」と述べた。 –

+0

こんにちは、 素早い応答をありがとうが、私は情報の重要な部分を含んでいなかったのでしょうか?私はオプションが毎回同じ順序である必要があります。また、情報が収集されるプログラムでは、確実に起こることを確実にする方法がありません。オプション番号に従ってそれらを連結することは可能ですか?また、私は静的なソリ​​ューションが動作するように5つ以上のオプションを持つことはありません知っている。 –

+4

グループ内のアイテムを注文するには、次のようにします。 GROUP_CONCAT(Ordered_Options.Value ORDER BY Ordered_Options.value)、 –

8

私は助けに感謝、私は誰かが、私はそれを感謝有効性についてコメントするならば、私は解決策を見つけたと思います。基本的に私がやったことは。あなたが本当にあなたの結果に複数の列を必要とし、オプションの量が制限されている場合することができます、

SELECT 
    ordered_item.id as `Id`, 
    ordered_item.Item_Name as `ItemName`, 
    Options1.Value 
    Options2.Value 
FROM ORDERED_ITEMS 
LEFT JOIN (Ordered_Options as Options1) 
    ON (Options1.Ordered_Item.ID = Ordered_Options.Ordered_Item_ID 
     AND Options1.Option_Number = 43) 
LEFT JOIN (Ordered_Options as Options2) 
    ON (Options2.Ordered_Item.ID = Ordered_Options.Ordered_Item_ID 
     AND Options2.Option_Number = 44); 
+4

これはメンテナンスが難しいでしょう。遅かれ早かれ、クライアントは3番目または4番目のオプションを持つことを望んでおり、それまでにすべてを書き直す必要があります。 –

+0

投稿したクエリと同じ結果を返す別の回答が追加されましたが、もう少し柔軟性があります。あなたは結果にピザオプションの複数の列を取得しながら、無制限のオプションを持つことができます。 –

1

(間違った構文を許して)私はそれがその実装に多少静的で実現するが、私はそれが何をする必要があるかありませんあなたは最高の選択肢の数が限られているために起こっている知っているなら、私はこの(順番あたり4つのオプションのmaxの一例)をしようとするだろう

select 
    ordered_item.id as `Id`, 
    ordered_item.Item_Name as `ItemName`, 
    if(ordered_options.id=1,Ordered_Options.Value,null) as `Option1`, 
    if(ordered_options.id=2,Ordered_Options.Value,null) as `Option2`, 
    if(ordered_options.id=43,Ordered_Options.Value,null) as `Option43`, 
    if(ordered_options.id=44,Ordered_Options.Value,null) as `Option44`, 
    GROUP_CONCAT(if(ordered_options.id not in (1,2,43,44),Ordered_Options.Value,null) as `OtherOptions` 
from 
    ordered_item, 
    ordered_options 
where 
    ordered_item.id=ordered_options.ordered_item_id 
group by 
    ordered_item.id 
1

:でも、これを行う

Select OI.ID, OI.Item_Name, OO1.Value, OO2.Value, OO3.Value, OO4.Value 

FROM Ordered_Items OI 
    LEFT JOIN Ordered_Options OO1 ON OO1.Ordered_Item_ID = OI.ID 
    LEFT JOIN Ordered_Options OO2 ON OO2.Ordered_Item_ID = OI.ID AND OO2.ID != OO1.ID 
    LEFT JOIN Ordered_Options OO3 ON OO3.Ordered_Item_ID = OI.ID AND OO3.ID != OO1.ID AND OO3.ID != OO2.ID 
    LEFT JOIN Ordered_Options OO4 ON OO4.Ordered_Item_ID = OI.ID AND OO4.ID != OO1.ID AND OO4.ID != OO2.ID AND OO4.ID != OO3.ID 

GROUP BY OI.ID, OI.Item_Name

gあなたがそうしなければならない重複のすべてを取り除きます。私はちょうど私が私の子供のテーブルに1つまたは2つの一致を持っていたことを知っていた私が働いているサイトで同様の何かを実装しました、そして、私は各親アイテムのために1つの行を持っていたことを確認したかった。

0

ここでは、このタイプの要件のクエリを作成する方法を示します。

select ID,Item_Name,max(Flavor) as Flavor,max(Extra_Cheese) as Extra_Cheese 
    from (select i.*, 
        case when o.Option_Number=43 then o.value else null end as Flavor, 
        case when o.Option_Number=44 then o.value else null end as Extra_Cheese 
       from Ordered_Item i,Ordered_Options o) a 
    group by ID,Item_Name; 

あなたは基本的に各ケースを「ケース」を使用して「ケースアウト」します。それぞれの目的の項目に対して「グループ化」を使用して、各列の「最大()」を選択します。

関連する問題