2010-08-16 5 views
2

Dire que j'ai quatre tables:Mysql Query Incorporating autoréférentiel Rejoignez

------------- features -------------- 
id: int 
name: varchar 
------------------------------------- 

-------- feature_categories --------- 
feature_id: int 
category_id: int  
------------------------------------- 

----------- categories -------------- 
id: int 
name: varchar  
------------------------------------- 

------ category_subcategories ------- 
category_id: int 
sub_category_id: int  
------------------------------------- 

catégorie a beaucoup de (sous) catégories, par autoréférentiel rejoindre les sous-catégories

Une fonctionnalité a plusieurs catégories, de ces autres seront sous-catégories, via join feature_categories

Ce dont j'ai besoin est d'envoyer un tableau d'identifiants de fonctions et un identifiant (principal) de catégorie et j'ai renvoyé toutes les sous-catégories. Cela s'avère plus difficile que je l'aurais espéré et j'apprécierais grandement toute aide. Faites-moi savoir si cette question n'est pas claire.

EDIT Je n'ai pas besoin de la table de caractéristiques pour être incluse dans une requête. Dans la facette, je n'ai besoin que du champ de nom de la sous-catégorie (catégorie) à retourner.

+0

est votre arbre de catégorie seulement de la profondeur 1? c'est-à-dire qu'une catégorie principale peut avoir des sous-catégories, mais celles-ci ne peuvent pas avoir de sous-catégories propres? Egalement - en dehors de mysql, utilisez-vous un langage ou une plate-forme de programmation? –

+0

Salut Yoni. Les catégories auront seulement une profondeur de 1. J'utilise du rubis sur des rails. – mark

+0

juste pour clarifier votre question: vous transmettez des identifiants de fonction et un identifiant de catégorie et vous voulez retourner toutes les sous-catégories - qui contiennent l'un des identifiants des entités transmises ET sont les parents de votre catégorie fournie - est-ce exact? – Nicolas78

Répondre

1

Devait travailler à travers ce un peu, mais soit ci-dessous devrait fonctionner. 2ème est probablement plus efficace:

select f.name featureName, 
    c.name CategoryName, 
    c2.name SubCategoryName 
    FROM features f, feature_categories fc, categories c, category_subcategories sc, categories c2, feature_categories fc2 
    WHERE f.id = fc.feature_id 
    AND c.id = fc.category_id 
    AND sc.category_id = c.id 
    and c2.id = sc.sub_category_id 
    and fc2.category_id = c2.id 
    AND f.id in (0,1,2,...) 
    and fc2.feature_id in (0,1,2,...) 
    AND c.id = @main_category_id 

ou:

select f.name featureName, 
    c.name CategoryName, 
    c2.name SubCategoryName 
     FROM features f 
     inner join feature_categories fc on f.id = fc.feature_id 
     inner join categories c on c.id = fc.category_id 
     inner join category_subcategories sc on sc.category_id = c.id 
     inner join categories c2 on c2.id = sc.sub_category_id 
     inner join feature_categories fc2 on fc.category_id = c2.id 

     WHERE f.id in (0,1,2,...) 
     AND c.id = @main_category_id 

     and fc2.feature_id in (0,1,2,...) 
+0

Ceci est l'un d'eux jointures moche. – Russ

+0

Faite une petite correction - devrait fonctionner maintenant. – Russ

+0

Merci Russ! La première solution fonctionne mais pas la seconde. J'ai supprimé la fonction join dont je n'ai pas besoin et référencé feature_categories.feature_id pour simplifier un peu la requête. Je vais laisser cela ouvert pour le moment et voir si une amélioration peut être faite. Merci encore. – mark

0

Est-ce que ce qui suit fait le travail?

SELECT * 
FROM `category_subcategories` sc 
    JOIN `categories` c ON sc.category_id = c.id 
    JOIN `feature_categories` fc ON fc.category_id = c.id 
WHERE fc.feature_id IN (0,1,2,...) 
    AND c.id = main_category_id; 
+0

Salut et merci pour votre réponse. J'ai peur que cela ne retourne pas les sous-catégories. – mark

+0

Cela semble proche, mais le nom de la catégorie jointe est la catégorie parente. – mark

0
select f.name featureName, 
    c.name CategoryName, 
    sc.name SubCategoryName 
from features f 
join features_categories fc on f.id=fc.feature_id 
join categories c on fc.category_id=c.id 
join category_subcategories cs on c.id=cs.category_id 
join categories sc on cs.sub_categories_id=sc.id 
WHERE f.id IN (0,1,2,...) 

Si je comprends bien ce que vous demandez ...

+0

Salut Joe et merci pour votre réponse. Cela fonctionne comme requis avec l'ID supplémentaire main_category passé: "and c.id = @main_category_id". Je vais aller le tester et voir si quelqu'un trouve une autre réponse. Cela semble bien, mais sql n'est pas mon point fort. – mark

+0

En fait, cela ne fonctionne pas avec mon amendement. Toutes les sous-catégories sont renvoyées, qu'elles soient jointes à l'une des entités ou non. – mark

+0

Dans ce cas, je ne comprends pas très bien ce dont vous avez besoin. Pour les fonctionnalités de (1,2, ...), vous avez besoin de toutes les sous-catégories liées à celles-ci ayant une catégorie spécifique. Avez-vous vérifié si toutes les fonctionnalités combinées ont toutes les sous-catégories (je ne sais pas si vous avez bien compris cette question ...)? Si vous essayez avec une seule fonctionnalité? Dans ce cas, renvoie-t-il les sous-catégories correctes? – user423975

0
select f.name featureName, 
c.name CategoryName, 
c2.name SubCategoryName 
FROM features f 
inner join feature_categories fc on f.id = fc.feature_id 
inner join categories c on c.id = fc.category_id 
inner join category_subcategories sc on sc.category_id = c.id 
inner join categories c2 on c2.id = sc.sub_category_id 
inner join feature_categories fc2 on fc.category_id = c2.id and fc2.feature_id = fc.feature_id 
WHERE f.id in (0,1,2,...) 
AND c.id = @main_category_id; 
0

Cela peut donner résultat attendu

select cat.name 
    from categories cat, 
     feature_categories feacat, 
     category_subcategories cat_subcat 
where feacat.feature_id in (1,2,3) 
    and feacat.category_id = cat.id 
    and exists(select 1 
       from cat_subcat 
       where category_id = @catid 
       and sub_category_id=cat.id 
      )