Programmation » SQL - Récursivité (sort of)
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 12:55:42,
Par SchnickBonjour les experts db,
Je suis confronté à un problème de données et de table à constituer dans un environnement SQL.
Le principe business est le suivant, j'ai une table qui comprend toutes les recettes (alimentaire) d'une entreprise de restauration (pas Quick :sol:)
En simplifié, la table est ainsi :
- Clé
- RecetteID
- IngrédientID
- SousRecetteID
- Quantité
Un recette peut donc être composée de 1..n ingrédients et/ou de 1..n sous-recettes auxquels sont à chaque fois associés une quantité.
Exemple :
Recette R1 est composée de :
Recette R2 est composée de:
etc.
Le nombre de sous-recettes (i.e. recette de recette) peut aller jusqu'à une hiérarchie de 7 niveaux mais je n'ai aucune garantie de stabilité à ce niveau.
Ce que j'ai besoin, c'est de créer une table (ou en tout cas d'extraire les données) avec toutes les recettes composées uniquement d'ingrédients. Donc je dois aller avec une sorte de récursivité aller chercher les ingrédients de toutes les sous-recettes et les associer à la recette de niveau 1.
J'ai essayé de le faire avec les requêtes récursives en utilisant les tables communes (CTE) mais je n'y arrive pas. Est-ce que quelqu'un peut m'aider ?
Je suis confronté à un problème de données et de table à constituer dans un environnement SQL.
Le principe business est le suivant, j'ai une table qui comprend toutes les recettes (alimentaire) d'une entreprise de restauration (pas Quick :sol:)
En simplifié, la table est ainsi :
- Clé
- RecetteID
- IngrédientID
- SousRecetteID
- Quantité
Un recette peut donc être composée de 1..n ingrédients et/ou de 1..n sous-recettes auxquels sont à chaque fois associés une quantité.
Exemple :
Recette R1 est composée de :
- - Ingrédient I1
- - Ingrédient I2
- - Ingrédient I3
- - SousRecette R2
- - SousRecette R3
Recette R2 est composée de:
- - Ingrédient I5
- - Ingrédient I6
- - SousRecette R4
etc.
Le nombre de sous-recettes (i.e. recette de recette) peut aller jusqu'à une hiérarchie de 7 niveaux mais je n'ai aucune garantie de stabilité à ce niveau.
Ce que j'ai besoin, c'est de créer une table (ou en tout cas d'extraire les données) avec toutes les recettes composées uniquement d'ingrédients. Donc je dois aller avec une sorte de récursivité aller chercher les ingrédients de toutes les sous-recettes et les associer à la recette de niveau 1.
J'ai essayé de le faire avec les requêtes récursives en utilisant les tables communes (CTE) mais je n'y arrive pas. Est-ce que quelqu'un peut m'aider ?
La mort, c'est un peu comme une connerie. Le mort, lui, il ne sait pas qu'il est mort. Ce sont les autres qui sont tristes. Le con, c'est pareil. Philippe Geluck
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 13:09:35,
Par PinouJe comprend pas bien ta [table qui comprend toutes les recettes] :
- Clé
- RecetteID
- IngrédientID
- SousRecetteID
- Quantité
Quantité est la quantité de l'ingrédient ou de la sous recette ?
IngrédientID et SousRecetteID peuvent tous deux contenir une valeur pour une même row ?
Si je devais le faire rapidement et sous réserve des perfs je ferait comme ça :
SELECT RecetteID
,SUM(CASE WHEN IngrédientID IS NULL THEN 0 ELSE 1 END) AS CountIngrédientID
,SUM(CASE WHEN SousRecetteID IS NULL THEN 0 ELSE 1 END) AS CountSousRecetteID
FROM [table qui comprend toutes les recettes]
GROUP BY RecetteID
HAVING CountIngrédientID > 0
AND CountSousRecetteID = 0
- Clé
- RecetteID
- IngrédientID
- SousRecetteID
- Quantité
Quantité est la quantité de l'ingrédient ou de la sous recette ?
IngrédientID et SousRecetteID peuvent tous deux contenir une valeur pour une même row ?
Si je devais le faire rapidement et sous réserve des perfs je ferait comme ça :
SELECT RecetteID
,SUM(CASE WHEN IngrédientID IS NULL THEN 0 ELSE 1 END) AS CountIngrédientID
,SUM(CASE WHEN SousRecetteID IS NULL THEN 0 ELSE 1 END) AS CountSousRecetteID
FROM [table qui comprend toutes les recettes]
GROUP BY RecetteID
HAVING CountIngrédientID > 0
AND CountSousRecetteID = 0
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 14:13:15,
Par SchnickMerci de ton retour mais je ne crois pas que cela fonctionnerait.
Un exemple pour illustrer.
La recette Steak :
Elle est composée de l'ingrédient Steak (qté 1) et de l'ingrédient Haricot Vert (Qté 50g)
Elle est également composée de la recette frites (50%) et de la recette purée (35%) et de la recette pomme de terre (15%)
La recette frites est composée de de l'ingrédient frites (130g), de l'ingrédient huile (30ml) et de la recette poivre et sel (Qté 1).
La recette poivre & sel est composée de l'ingrédient poivre à 1g et de sel à 1.5g.
Ce que je voudrais obtenir c'est la recette steak =
- Ingrédient Steak 1 pièce
- Haricot Vert 50 grammes
- Frites 65g (50% de la recette)
- Huile 15 ml (50% de la recette)
- Poivre 0.5g (50% de la recette de la recette)
- Sel 0.75g) (50% de la recette de la recette)
- etc. avec les autres ingrédients...
Pour l'exemple, dans ma table source (LignesDeRecettes) j'aurai :
Clé1 RecetteSteak Steak null 1 pièce
Clé1 RecetteSteak Haricot null 50 gramme
Clé1 RecetteSteak null RecetteFrite 50 %
Clé1 RecetteSteak null RecettePurée 35 %
Clé1 RecetteSteak null RecettePdt 15 %
Clé2 RecetteFrite Frites null 130 gramme
Clé2 RecetteFrite Huile null 30 ml
Clé2 RecetteFrite null RecetteP&Sel 1 pièce
Clé3 RecetteP&Sel Poivre null 1 gramme
Clé3 RecetteP&Sel Sel null 1.5 gramme
Et je voudrais
Clé1 RecetteSteak ingré1 qté unité
Clé1 RecetteSteak ingré2 qté unité
etc.
J'espère que c'est plus clair.
Un exemple pour illustrer.
La recette Steak :
Elle est composée de l'ingrédient Steak (qté 1) et de l'ingrédient Haricot Vert (Qté 50g)
Elle est également composée de la recette frites (50%) et de la recette purée (35%) et de la recette pomme de terre (15%)
La recette frites est composée de de l'ingrédient frites (130g), de l'ingrédient huile (30ml) et de la recette poivre et sel (Qté 1).
La recette poivre & sel est composée de l'ingrédient poivre à 1g et de sel à 1.5g.
Ce que je voudrais obtenir c'est la recette steak =
- Ingrédient Steak 1 pièce
- Haricot Vert 50 grammes
- Frites 65g (50% de la recette)
- Huile 15 ml (50% de la recette)
- Poivre 0.5g (50% de la recette de la recette)
- Sel 0.75g) (50% de la recette de la recette)
- etc. avec les autres ingrédients...
Pour l'exemple, dans ma table source (LignesDeRecettes) j'aurai :
Clé1 RecetteSteak Steak null 1 pièce
Clé1 RecetteSteak Haricot null 50 gramme
Clé1 RecetteSteak null RecetteFrite 50 %
Clé1 RecetteSteak null RecettePurée 35 %
Clé1 RecetteSteak null RecettePdt 15 %
Clé2 RecetteFrite Frites null 130 gramme
Clé2 RecetteFrite Huile null 30 ml
Clé2 RecetteFrite null RecetteP&Sel 1 pièce
Clé3 RecetteP&Sel Poivre null 1 gramme
Clé3 RecetteP&Sel Sel null 1.5 gramme
Et je voudrais
Clé1 RecetteSteak ingré1 qté unité
Clé1 RecetteSteak ingré2 qté unité
etc.
J'espère que c'est plus clair.
La mort, c'est un peu comme une connerie. Le mort, lui, il ne sait pas qu'il est mort. Ce sont les autres qui sont tristes. Le con, c'est pareil. Philippe Geluck
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 14:16:53,
Par zionEt tu dois en sortir quoi? Une table à afficher, ou autre chose?
toujours se dire que la seule solution vient du SQL le cas échéant? Tu as des gigas de recettes? Non, ce ne sont que des IDs, non? Pourquoi ne pas faire un simple query pour mettre cela en mémoire, puis de parcourir ton arbre et de compter. En terme de performance, à moins d'avoir le query idéal, tu auras certainement un meilleur résultat.
Quitte, si tu as besoin d'aller chercher plus d'infos après, à ne faire ta sélection que sur base des ids trouvés (bon après si t'as 200.000 ids, on en reparle bien sûr, mais c'est plus simple de maîtriser le O() de ton algo que celui de ton query).
toujours se dire que la seule solution vient du SQL le cas échéant? Tu as des gigas de recettes? Non, ce ne sont que des IDs, non? Pourquoi ne pas faire un simple query pour mettre cela en mémoire, puis de parcourir ton arbre et de compter. En terme de performance, à moins d'avoir le query idéal, tu auras certainement un meilleur résultat.
Quitte, si tu as besoin d'aller chercher plus d'infos après, à ne faire ta sélection que sur base des ids trouvés (bon après si t'as 200.000 ids, on en reparle bien sûr, mais c'est plus simple de maîtriser le O() de ton algo que celui de ton query).
Je suis le Roy
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 14:17:38,
Par zion
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 14:29:20,
Par SchnickJe dois sortir des ventes par ingrédient au final de mon rapport.
J'ai un table avec les ventes de produits : x steak
Je dois avoir : x tranches steak, x grammes de haricots, etc.
EDIT : La table des ventes n'est évidemment pas la même que la table contenant les lignes de recettes.
Compter je veux bien mais je n'arrive pas à faire le saut (intellectuel) de comment va être pris en compte la recette de recette de recette de recette. Je ne peux pas compter le nombre d’occurrences puisque chaque recette peut être rappelée par n'importe quelle autre recette.
Mais c'est peut-être moi auquel il manque une case
Dernière édition: 06/10/2015 @ 14:31:10
J'ai un table avec les ventes de produits : x steak
Je dois avoir : x tranches steak, x grammes de haricots, etc.
EDIT : La table des ventes n'est évidemment pas la même que la table contenant les lignes de recettes.
Compter je veux bien mais je n'arrive pas à faire le saut (intellectuel) de comment va être pris en compte la recette de recette de recette de recette. Je ne peux pas compter le nombre d’occurrences puisque chaque recette peut être rappelée par n'importe quelle autre recette.
Mais c'est peut-être moi auquel il manque une case
Dernière édition: 06/10/2015 @ 14:31:10
La mort, c'est un peu comme une connerie. Le mort, lui, il ne sait pas qu'il est mort. Ce sont les autres qui sont tristes. Le con, c'est pareil. Philippe Geluck
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 19:56:41,
Par zionT'as pas des millions de recettes, si?
Ce que je ferais, un array statique, pour taille le plus grand id de recette. Ca va bouffer qqs KB de mémoire, pas grave. Tu y charges chaque recette avec un array pour les ingrédients, et un array pour les ids des sous recettes.
Puis, tu te fais un array avec les produits, tous à 0, même chose, de la taille du plus grand id, avec ce que tu as besoin pour ton rapport déjà lié (le nom du produit, etc).
Puis tu fais simplement ton query des ventes, et pour chaque ligne, tu parcours ton array.
Je te promets que ce sera ultra rapide, même avec des dizaines de milliers de rows, vu que tu t'indexes toi même ton truc grâce à tes ids.
Sinon tu peux le faire en SQL pur, mais vu que tu as pas de certitude de ton degré de récursivité, soit tu t'en forces un, soit t'es parti pour la gloire.
Ce que je ferais, un array statique, pour taille le plus grand id de recette. Ca va bouffer qqs KB de mémoire, pas grave. Tu y charges chaque recette avec un array pour les ingrédients, et un array pour les ids des sous recettes.
Puis, tu te fais un array avec les produits, tous à 0, même chose, de la taille du plus grand id, avec ce que tu as besoin pour ton rapport déjà lié (le nom du produit, etc).
Puis tu fais simplement ton query des ventes, et pour chaque ligne, tu parcours ton array.
Je te promets que ce sera ultra rapide, même avec des dizaines de milliers de rows, vu que tu t'indexes toi même ton truc grâce à tes ids.
Sinon tu peux le faire en SQL pur, mais vu que tu as pas de certitude de ton degré de récursivité, soit tu t'en forces un, soit t'es parti pour la gloire.
Je suis le Roy
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 22:22:38,
Par PinouOK, donc en effet, j'avais rien compris
Je pensais que tu voulais sortir la liste de "toutes les recettes composées uniquement d'ingrédients."
Je vais relire pour essayer de comprendre.
Je pensais que tu voulais sortir la liste de "toutes les recettes composées uniquement d'ingrédients."
Je vais relire pour essayer de comprendre.
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 22:43:04,
Par SchnickT'as pas des millions de recettes, si?
Ce que je ferais, un array statique, pour taille le plus grand id de recette. Ca va bouffer qqs KB de mémoire, pas grave. Tu y charges chaque recette avec un array pour les ingrédients, et un array pour les ids des sous recettes.
Puis, tu te fais un array avec les produits, tous à 0, même chose, de la taille du plus grand id, avec ce que tu as besoin pour ton rapport déjà lié (le nom du produit, etc).
Puis tu fais simplement ton query des ventes, et pour chaque ligne, tu parcours ton array.
Je te promets que ce sera ultra rapide, même avec des dizaines de milliers de rows, vu que tu t'indexes toi même ton truc grâce à tes ids.
Sinon tu peux le faire en SQL pur, mais vu que tu as pas de certitude de ton degré de récursivité, soit tu t'en forces un, soit t'es parti pour la gloire.
Ce que je ferais, un array statique, pour taille le plus grand id de recette. Ca va bouffer qqs KB de mémoire, pas grave. Tu y charges chaque recette avec un array pour les ingrédients, et un array pour les ids des sous recettes.
Puis, tu te fais un array avec les produits, tous à 0, même chose, de la taille du plus grand id, avec ce que tu as besoin pour ton rapport déjà lié (le nom du produit, etc).
Puis tu fais simplement ton query des ventes, et pour chaque ligne, tu parcours ton array.
Je te promets que ce sera ultra rapide, même avec des dizaines de milliers de rows, vu que tu t'indexes toi même ton truc grâce à tes ids.
Sinon tu peux le faire en SQL pur, mais vu que tu as pas de certitude de ton degré de récursivité, soit tu t'en forces un, soit t'es parti pour la gloire.
L'idée est séduisante, faut juste que je me renseigne sur le comment faire un array.
Puis faut des arrays deux dimensions, recette | sous recette et recette | ingredients, non. Sinon je parcourerais un table sans référence à la recette et je ne saurai pas faire le lien entre le produit et la recette.
La mort, c'est un peu comme une connerie. Le mort, lui, il ne sait pas qu'il est mort. Ce sont les autres qui sont tristes. Le con, c'est pareil. Philippe Geluck
SQL - Récursivité (sort of)
Publié le 06/10/2015 @ 22:49:18,
Par philanthropeBonsoir,
Je pense que la réponse se trouve au moins à cette adresse: http://stackoverflow.com/questions/20215744/how-to-create-a-mysql-hierarchical-recursive-query
Il y a bcp d'autres exemples. Le mots clés sont: mysql requête récursive arborescence
Je pense que la réponse se trouve au moins à cette adresse: http://stackoverflow.com/questions/20215744/how-to-create-a-mysql-hierarchical-recursive-query
Il y a bcp d'autres exemples. Le mots clés sont: mysql requête récursive arborescence
SQL - Récursivité (sort of)
Publié le 07/10/2015 @ 09:49:07,
Par SchnickBonsoir,
Je pense que la réponse se trouve au moins à cette adresse: http://stackoverflow.com/questions/20215744/how-to-create-a-mysql-hierarchical-recursive-query
Il y a bcp d'autres exemples. Le mots clés sont: mysql requête récursive arborescence
Je pense que la réponse se trouve au moins à cette adresse: http://stackoverflow.com/questions/20215744/how-to-create-a-mysql-hierarchical-recursive-query
Il y a bcp d'autres exemples. Le mots clés sont: mysql requête récursive arborescence
Oui j'ai commencé par Google et donc ici ou là mais n'étant pas un expert je me suis retrouvé bloqué. Je n'arrive pas à appliquer les exemples à mon cas pratique.
Bon, sachant que je devais mettre les données à disposition d'un cube cognos, je vais les donner en l'état et c'est lui qui va s'occuper de la récursivité. Donc problème résolu pour le client.
Mais je vais quand même essayer de trouver comment faire.
EDIT : c'est marrant dans la prévisualisation le lien fonctionne mais pas dans l'affichage final
Dernière édition: 07/10/2015 @ 11:14:20
La mort, c'est un peu comme une connerie. Le mort, lui, il ne sait pas qu'il est mort. Ce sont les autres qui sont tristes. Le con, c'est pareil. Philippe Geluck
SQL - Récursivité (sort of)
Publié le 07/10/2015 @ 10:40:48,
Par zionc'est [url = lelien ] plop [ / url ]
Je suis le Roy
SQL - Récursivité (sort of)
Publié le 07/10/2015 @ 11:13:22,
Par SchnickIl apprécie pas les guillemets. Mais c'est amusant qu'en prévisionnage çà passe.
Dernière édition: 07/10/2015 @ 11:13:59
Dernière édition: 07/10/2015 @ 11:13:59
La mort, c'est un peu comme une connerie. Le mort, lui, il ne sait pas qu'il est mort. Ce sont les autres qui sont tristes. Le con, c'est pareil. Philippe Geluck
SQL - Récursivité (sort of)
Publié le 07/10/2015 @ 16:18:47,
Par PinouPas mal comme solution.
Je n'avais jamais utilisé de CTE avec UNION ALL.
Je viens de l'appliquer dans une DB pour améliorer requête moins propre et légèrement buguée.
Mais puisque tu n'en a plus besoin, j'ai pas trop le courage d'essayer de le refaire pour ta tale de recette.
Je n'avais jamais utilisé de CTE avec UNION ALL.
Je viens de l'appliquer dans une DB pour améliorer requête moins propre et légèrement buguée.
Mais puisque tu n'en a plus besoin, j'ai pas trop le courage d'essayer de le refaire pour ta tale de recette.