MySQL中的复杂SELECT查询

pan*_*nic 2 mysql sql tags select join

我有以下表格:

articles: id, title, content
tags: id, tag, tagCategory
tags2articles: id, idTag, idArticle
categories: id, title, someOtherFields
Run Code Online (Sandbox Code Playgroud)

在页面中,我需要选择所有具有多个标签的文章.我正在使用这个:

SELECT
   SQL_CALC_FOUND_ROWS a.* 
FROM 
  articles AS a
  JOIN tags2articles AS ta  ON a.id=ta.idArticle
  JOIN tags AS t ON ta.idTag=t.id
WHERE 
  t.id IN (12,13,16) 
GROUP BY a.id
HAVING
  COUNT(DISTINCT t.id)=3
Run Code Online (Sandbox Code Playgroud)

这将选择所有具有ID为12,13和16的标签的文章,并且它可以正常工作.但是,所选文章可能还有其他标签,这些标签可能只针对其中一个或多个.

这里有一个棘手的部分:我想使用这些标签来制作一些过滤器,所以我需要另一个查询来选择上面文章所有的不同标签.像这样的东西:

?????????????????????????????????????????????
? TagID ? Tag  ? Category  ? SomeOtherField ?
?????????????????????????????????????????????
? id1   ? tag1 ? category1 ? field1         ?
? id2   ? tag2 ? category2 ? field2         ?
? id3   ? tag3 ? category1 ? field1         ?
? id4   ? tag4 ? category3 ? field3         ?
?????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

Mic*_*ski 5

使用您已经拥有的类似查询作为要加入的派生表(但没有所有a.*列),您可以执行INNER JOIN反对tags2articles以获取这些文章ID所具有的其余标记.

这应该导致任何匹配文章持有的所有标签的不同列表.

SELECT 
  DISTINCT
  t.id,
  t.tag, 
  c.title AS Category
FROM
  tags2Articles t2a 
  INNER JOIN tags t ON t.id = t2a.idTag
  INNER JOIN categories c ON t.tagCategory = c.id
  /* Subquery join returns article ids having all 3 tags you filtered */
  /* Joining against tags2articles again will get the remaining tags for these articles */
  INNER JOIN (
    SELECT
     a.id 
    FROM 
     articles AS a
     JOIN tags2articles AS ta  ON a.id=ta.idArticle
     JOIN tags AS tsub ON ta.idTag=tsub.id
    WHERE 
      tsub.id IN (12,13,16) 
    GROUP BY a.id
    HAVING COUNT(DISTINCT tsub.id)=3 
  ) asub ON t2a.idArticle = asub.id
Run Code Online (Sandbox Code Playgroud)