I have a problem with implementing a module where one project can belong to multiple categories. Example: project “PHP Programmer” belongs to categories: Programming, PHP.
Assuming the following query (select projects that belong to categories 1,3,11):
SELECT projects.* FROM projects
LEFT JOIN pojects_category on projects.id = pojects_category.project_id
WHERE pojects_category.category_id IN (1,3,11) and projects.id='94'`
I get a the same project returned twice, because there are 2 matches in the project_category table for the project_id = 94
Table projects_category schema:
CREATE TABLE IF NOT EXISTS `pojects_category` (
`project_id` int(10) NOT NULL,
`category_id` int(10) NOT NULL,
KEY `category_id` (`category_id`),
KEY `project_id` (`project_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `pojects_category` (`project_id`, `category_id`) VALUES
(94, 3),
(94, 1);
Am I missing something?
Solution: use GROUP BY or DISTINCT
No, this is fine. This is just one of the rare cases when you want to use the
DISTINCTkey word to remove duplicates.In this case this is justified by the fact that the logic of the query is correct, even though it returns more than one row. Many times one can see the usage of
DISTINCTwhen actually the logic of the query is wrong.Side-note:
WHEREclause other thanIS NULL/IS NOT NULLwould make anyLEFT JOINon this same table reference turn to anINNER JOIN, as for the final resultset behaviour. (see this: https://stackoverflow.com/a/15483895/1291428)you ought not use
GROUP BYto simulate the effect ofDISTINCT, for 2 reasons:1/ This is just not the purpose. One of the effects of
GROUP BYis to eliminate duplicates, but its main purpose is to group rows according to a certain set of criteria, in order to apply some analytic calculations/operations on them.2/
GROUP BYalsoORDER BYthe results (in mysql), which is not necessarly what you want and in that case slows down the execution. Please, just ensure appropriate use of what the engines are providing, that’s always better from the point of view of forward compatibility. (anticipating that what you include as granted is actually not)regards.