Pour les pros du SQL (prb avec récursivité) - SQL/NoSQL - Programmation
Marsh Posté le 10-08-2010 à 15:34:32
SELECT news_id, flux_id FROM news_in_flux WHERE flux_id IN (ma_liste_de flux) AND EXISTS (SELECT * FROM flux JOIN company ON flux.company_id = company.company_id WHERE flux.flux_id = news_in_flux.flux_id AND company.company_group_id IS NULL)
Mais je tappe un peu au pif
Marsh Posté le 10-08-2010 à 15:41:13
merci alien, je vais essayer ça, je comprends pas toute la requête mais intuitivement, j'ai l'impression que ça ne peut pas marcher s'il y a plusieurs niveaux de récursivité dans les sociétés (une société appartient à une société qui appartient à une autre société...), je me trompe?
Marsh Posté le 10-08-2010 à 16:06:08
Je fais la supposition erronée que la company à la racine possède le flux en question. Je pense que tout problème est insolvable avec une simple requête, tu as besoin de procédure stockée.
Marsh Posté le 10-08-2010 à 16:11:12
Ok, c'est ce que je me disais aussi.
J'avais pensé à l'éventualité d'enregistrer la hiérarchie complète dans une colonne et ensuite de comparer cette arbo pour savoir quel était la société le plus haut dans la hiérarchie mais sinon je voyais pas comment le faire.
Apparemment, postgresql gère les requêtes récursives, c'était ma 2e solution.
Marsh Posté le 11-08-2010 à 09:20:20
En ajoutant 2 colonnes ya moyen de faire ce que tu veux en une seule query.
Dans la table company il faut ajouter une colonne company_level et company_source (meme data type que company_id).
Tu mets company_level = 0 where company_group_id is NULL, sinon quand tu rajoutes un company tu mets company_level = parentcompany.company_level + 1.
Tu mets company_source = company_id where company_group_id is NULL, pour les autres tu mets company_source = parentcompany.company_source.
En gros, le company_level sert a trouver la company la plus "haute" dans la hierarchie, le company_source permet de faire un group by et separer les differents groupes de company.
En SQL Server pour remplire company_source et company_level la toute premiere fois tu peux faire ca:
Code :
|
Ensuite quand tu ajoutes une company il te suffit de connaite le company_level et company_source du parent (si il y en a un) et de l'inserer directement.
Si tu modifies la hierarchie d'une company tu remets le tout a jour en refesant tourner la query d'initialisation.
Pour trouver la liste de news unique et leur flux tu peux faire ca:
Code :
|
Tu peux toujours avoir des doublons si des company qui ont la meme _source et le meme _level ont les meme news, dans ce cas la tu peux faire ca (change MIN en autre chose si tu ne veux pas la premiere company par order alphabetique):
Code :
|
En general ce n'est pas super de sauver les niveau de hierarchie comme ca, ca peu devenir lourd a gerer en cas de mise a jour frequente, mais dans ton cas je suppose que tu vas passer plus de temps a ajouter des company plutot que de les deplacer dans la hierarchie.
Ce n'est jamais facil d'expliquer des queries hierarchique, donc si ca peu t'aider voici la totalité du code que j'ai utilisé pour ton probleme (les noms et hierarchie des company ne sont pas correcte, mais c'est le matin et j'ai pas plus d'idée que ca ):
Code :
|
Marsh Posté le 11-08-2010 à 09:34:39
Merci Oliiii pour cette longue réponse, j'imagine que tu as dû y passer pas mal de temps. Je vais regarder ça plus en détail et essayer de comprendre les requêtes. Je suis sur la requête en ce moment même et je pense avoir trouvé une solution qui permette de le faire sans recourir à des colonnes supplémentaires justement (ce qui m'embêtait un peu en terme de maintenance). Mais avoir une colonne company_level ou company_source peut toujours être utile. Je vais privilégier la solution la plus optimisée sachant que la majorité des requêtes vont être effectivement des SELECT pour récupérer les news tandis que les mises à jour de sociétés ou les changements dans la hiérarchie seront très limités.
Je reviens vers toi
Marsh Posté le 11-08-2010 à 12:48:17
'Tention je balance juste l'idée comme ca, mais y aurait pas moyen de faire quelque chose de similaire sans avoir à créer les deux colonnes mais en les générant sur le coup dans une sous-requete, en utilisant une clause CONNECT BY?
Un truc du genre:
SELECT level AS company_level, CONNECT_BY_ROOT company_group_id AS company_source |
Edit: ha oui, Oracle only je suppose par contre...
Marsh Posté le 11-08-2010 à 13:35:44
Il ya moyen de faire l'equivalent en SQL Server, le probleme est que les performances vont se degrader tres tres vite.
Les colonnes supplementaire sont la pour eviter de recalculer la meme chose a chaque Select (en partant du principe qu'on va faire beaucoup plus de Select/Insert que d'update).
Marsh Posté le 11-08-2010 à 14:47:10
Agreed.
Marsh Posté le 11-08-2010 à 19:28:37
Oliiii a écrit : Pleins de choses |
J'y ai pensé mais j'avais trop la fleme de l'expliquer. Chapeau d'avoir eu le courage.
Marsh Posté le 17-08-2010 à 23:52:27
J'ai finalement utiliser ta solution Oli qui me parait la meilleure.
Merci beaucoup pour ton aide !
Marsh Posté le 10-08-2010 à 15:01:32
Bonjour, je cherche à effectuer une requête SQL mais je ne trouve pas comment.
Voici l'idée.
J'ai une table `news` avec les news
news_id | news
J'ai une table `flux` avec les flux d'information
flux_id | flux | company_id
J'ai une table `company` avec les sociétés (mais chaque société peut appartenir à une autre société/groupe, donc la base est récursive)
company_id | company | company_group_id
J'ai une table `news_in_flux` de correspondance entre les news et le flux
flux_id | news_id
sachant que chaque news peut appartenir à plusieurs flux
Je souhaiterais faire une requête qui me permette de récupérer toutes les news dans une liste de flux données, mais vu qu'il peut y avoir des doublons car une même news peut être dans plusieurs flux, je ne veux récupérer que la news du flux de la société la plus haute dans la hiérarchie. (vous comprenez?)
Du coup, pour le moment, je fais un "select distinct news_id from flux, where flux IN (ma_liste_de_flux)" ce qui me retourne les news sans doublon, mais je ne sais plus de quel flux il provient.
Toute idée est la bienvenue.