Merci d'avance, je n'arrive pas à comprendre!
J'ai deux tables
Ordered_Item
ID | Item_Name 1 | Pizza 2 | Stromboli
Ordered_Options
Ordered_Item_ID | Option_Number | Valeur 1 43 Pepperoni 1 44 Extra Cheese 2 44 Extra Cheese
Ce que je cherche à produire est une requête mysql est quelque chose à cet effet
Sortie
ID | Item_Name | Option_1 | Option_2 1 Pizza Pepperoni Extra Cheese 2 Stromboli NULL Extra Cheese
J'ai essayé de nombreuses options se terminant le plus par une erreur de syntaxe, j'ai essayé group_concat mais ce n'est pas vraiment ce que je recherche. J'ai un exemple grossier ci-dessous de ce que je pense pourrait être un début. J'ai besoin que les options soient dans le même ordre à chaque fois. Et dans le programme où les informations sont collectées, il n'y a aucun moyen de garantir de manière fiable que cela se produira. Est-il possible de les faire concaténer selon le numéro d'option. Je sais aussi que je n'aurai jamais plus de 5 options, donc une solution statique fonctionnerait
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;
Merci! Joe
Le moyen le plus simple serait d'utiliser ici la fonction de groupe 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
Ce qui produirait:
Id ItemName Options
1 Pizza Pepperoni,Extra Cheese
2 Stromboli Extra Cheese
De cette façon, vous pouvez avoir autant d'options que vous le souhaitez sans avoir à modifier votre requête.
Ah, si vous voyez que vos résultats sont rognés, vous pouvez augmenter la taille limite de GROUP_CONCAT comme ceci:
SET SESSION group_concat_max_len = 8192;
J'apprécie l'aide, je pense que j'ai trouvé une solution si quelqu'un commentait l'efficacité je l'apprécierais. Ce que j'ai fait, c'est essentiellement. Je me rends compte qu'il est quelque peu statique dans son implémentation mais je fais ce dont j'ai besoin (pardonnez une syntaxe incorrecte)
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);
Si vous avez vraiment besoin de plusieurs colonnes dans votre résultat et que le nombre d'options est limité, vous pouvez même le faire:
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
Si vous savez que vous allez avoir un nombre limité d'options max alors j'essaierais ceci (exemple pour max de 4 options par commande):
Sélectionnez 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. ID! = OO1.ID ET OO3.ID! = OO2.ID JOIN GAUCHE Ordered_Options OO4 ON OO4.Ordered_Item_ID = OI.ID AND OO4.ID! = OO1.ID AND OO4.ID! = OO2.ID ET OO4.ID! = OO3.ID GROUPE PAR OI.ID, OI.Item_Name
La condition de regroupement supprime tous les doublons que vous obtiendriez autrement. Je viens d'implémenter quelque chose de similaire sur un site sur lequel je travaille, où je savais que j'aurais toujours 1 ou 2 correspondances dans ma table enfant, et je voulais m'assurer que je n'avais qu'une seule ligne pour chaque élément parent.
Voici comment vous construisez votre requête pour ce type d'exigence.
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;
Fondamentalement, vous "cassez" chaque colonne en utilisant case when
, Puis sélectionnez la max()
pour chacune de ces colonnes en utilisant group by
Pour chaque élément prévu.
Ce que vous voulez s'appelle un pivot, et ce n'est pas directement pris en charge dans MySQL, consultez cette réponse pour les options que vous avez:
Comment faire pivoter un schéma de valeur d'attribut d'entité MySQL