2009-09-16 5 views
1

Je crois que j'ai une mauvaise conception de base de données et que j'ai besoin d'aide pour l'améliorer. J'ai trois tables pour mes articles de blog.Conception de MySQL, requête, lignes dubliquées

Posts 
-id 
-title 

Categories 
-id 
-name 

CategoryBindings 
-id 
-postId 
-categoryId 

Disons que j'ai ces données:

Posts 
1 Title1 
2 Title2 

Categories 
1 category1 
2 category2 

CategoryBindings 
1 1 1 
2 1 2 
3 2 1 

La requête J'utilise maintenant pour obtenir mes messages avec leurs catégories sont

SELECT `p`.*, `cb`.`categoryId`, `c`.`name` AS `categoryName` 
FROM `Posts` AS `p` 
LEFT JOIN `CategoryBindings` AS `cb` ON p.id = cb.postId 
LEFT JOIN `Categories` AS `c` ON cb.categoryId = c.id 

Ce qui donne le résultat suivant:

1 Title1 1 category1 
1 Title1 2 cateogry2 
2 Title2 1 cateogry1 

Je reçois un blicate de poste 1 car ils sont deux categoryBindings pour cela. J'ai écrit un code qui avec php corrige le résultat de sorte que je reçois.

1 Title1 array(1 category1, 2 category2) 
2 Title2 array(1 category1) 

et cela a bien fonctionné jusqu'à ce que je me souvienne que j'ai besoin d'utiliser la limite avec dans mes requêtes. Je souhaite afficher 10 messages par page, mais je ne peux pas utiliser de limite car ma requête renvoie des lignes dupliquées. Est-ce un moyen de changer ma requête pour la faire fonctionner comme je veux, ou dois-je refaire mes tables? Si oui, comment me recommanderiez-vous de revoir mes tables?

Répondre

1

Vous pouvez utiliser GROUP_CONCAT ET CONCAT_WS:

SELECT `p`.`id`, `p.title`, GROUP_CONCAT(CONCAT_WS(' ', `cb`.`categoryId`, `c`.`name`)) AS `categoryNames` 
FROM `Posts` AS `p` 
LEFT JOIN `CategoryBindings` AS `cb` ON p.id = cb.postId 
LEFT JOIN `Categories` AS `c` ON cb.categoryId = c.id 
GROUP BY id, title 

A propos: Vous ne devriez pas SELECT * dans le code, mieux écrire ce que vous voulez explicitement. Cela évite les surcharges inutiles si vous ajoutez une colonne qui n'est pas utilisée dans le code et échouera tôt si vous supprimez/renommez une colonne.

+0

Merci, exactement ce que je demandais. – unkownt

Questions connexes