多对多关系查询好吗?

时间:2014-04-04 23:38:56

标签: mysql

所以我想知道你将如何编写以下查询。我已经想出了如何得到我想要的东西,但我确信它可以做得更好,我的解决方案有点......好吧......不应该如何:)

所以我有3张桌子,第一张是“文章”,其中存放文章(用于商店),然后购买“类别”,例如男装,女装,裤子,衬衫等,以及用于连接文章的枢轴表到多个类别。典型的多对多关系。

1)文章(身份证,姓名,价格......)

2)类别(id,name,...)

3)article_categories(article_id,category_id)

我想要检索名称为“男装”和“裤子”的所有类别的文章。请记住,可能会扩展查询以获取更多类别的文章。如果它们属于所有类别,则只应返回它们,而不仅仅是其中之一!现在我设法让它使用以下查询来检查GROUP BY中的类别数是否与WHERE子句中的类别数相同:

SELECT articles.* 
FROM articles a, categories c, article_categories ac
WHERE ac.article_id = a.id
AND ac.category_id = c.id
AND (
c.name =  'menswear'
OR c.name =  'pants'
)
GROUP BY a.id
HAVING COUNT( c.id ) =2

那你怎么写这个查询呢?

谢谢:)

1 个答案:

答案 0 :(得分:1)

在你的情况下,这种方式可能会更有效(更快)...

SELECT a.* FROM
(
  SELECT ac.article_id
  FROM categories AS c
  JOIN article_categories AS ac
  ON c.id = ac.category_id
  AND c.`name` IN ('menswear', 'pants')
  GROUP BY ac.article_id
  HAVING COUNT(DISTINCT c.`name`) = 2
) AS ArticleIDs
JOIN
articles AS a
ON ArticleIDs.article_id=a.id;

它避免同时进行三重连接。相反,它只是从categoriesarticle_categories进行连接并在此之后检查HAVING条件。然后,您可以在外部查询中为最终连接获取更小的结果集。

请参阅SQLFiddle

如果您的表具有唯一约束检查​​,您可以跳过我使用的DISTINCT子句并使用原始版本的HAVING条件。

如果实际上生产速度更快,那将会很棒。