MySQL Query显示基于多个过滤器/标签的结果

时间:2013-10-09 15:37:15

标签: mysql sql

之前有人以不同的方式提出这个问题,但我似乎找不到能满足我需要的东西。

此处的目标是根据所选标记创建一个返回照片的搜索查询。许多标签可以同时应用于过滤器,这需要使其能够使查询仅返回已选择所有标签的照片。想想在执行基本关键字搜索后缩小结果的任何主要网店。

表1:照片     ID |标题|描述| URL |创建

表2:PhotosTagsXref     ID | PHOTOID | TAGID

表3:PhotosTags     ID |标题|分类

我有什么:

SELECT p.* FROM `PhotosTagsXref` AS pt
LEFT JOIN `Photos` AS p ON p.`ID` = pt.`PhotoId`
LEFT JOIN `PhotosTags` AS t ON pt.`TagId` = t.`ID`
WHERE p.`Description` LIKE "%test%" AND 
????
GROUP BY p.`ID`
ORDER BY p.`Created` DESC LIMIT 20

????是我尝试了很多东西的地方,但是难倒了。问题是我可以很容易地找到包含带有一个或多个标签的照片的结果集,但是如果应用2,3或4个标签,我们只需要返回包含数据库中所有这些标签的条目的照片。我认为这将涉及结合结果集,但不是100%肯定。

实施例: 照片1标签:蓝色,白色,红色 照片2标签:蓝色

搜索带有“蓝色”标签的照片会返回两张照片,搜索带有“蓝色”和“白色”标签的照片只会返回照片1。

3 个答案:

答案 0 :(得分:1)

假设所请求的一组标签是(redblue),您可以这样做:

SELECT * FROM `Photos` 
WHERE `Description` LIKE "%test%" 
AND `ID` IN (
  SELECT pt.`PhotoId` FROM `PhotosTagsXref` AS pt
  JOIN `PhotosTags` AS t ON pt.`TagId` = t.`ID`
  WHERE t.Title in ('red','blue') /* your set here */
  GROUP BY pt.`PhotoId` HAVING COUNT(DISTINCT t.`TagId`)=2 /* # of tags */
  )
ORDER BY `Created` DESC LIMIT 20

显然,需要动态创建标签集及其计数。

注意:我正在计算DISTINCT TagID,因为我不知道你的表的约束。如果PhotosTagsXRef有PK / UNIQUE(PhotoIdTagId)且PhotosTags有PK / UNIQUE(TagId),那么COUNT(*)会就足够了。

答案 1 :(得分:0)

不可否认有点难看。但假设PhotosTags.Category有“蓝色”,“白色”等,请沿着这条线尝试。

SELECT p.* 
From `Photos` AS p
WHERE p.`Description` LIKE "%test%" AND 
  AND Exists
      ( Select 1 FROM `PhotosTagsXref` AS pt
        Inner JOIN `PhotosTags` AS t ON pt.`TagId` = t.`ID`
        Where pt.`PhotoId` = p.`ID`
          And t.Category = 'FirstCatToSearch'
      )   
  AND Exists
      ( Select 1 FROM `PhotosTagsXref` AS pt
        Inner JOIN `PhotosTags` AS t ON pt.`TagId` = t.`ID`
        Where pt.`PhotoId` = p.`ID`
          And t.Category = 'SecondCatToSearch'
      )   
  AND Exists
      ( ...
      )   
      ...

答案 2 :(得分:0)

SELECT p.* FROM `PhotosTagsXref` AS pt
LEFT JOIN `Photos` AS p ON p.`ID` = pt.`PhotoId`
LEFT JOIN `PhotosTags` AS t ON pt.`TagId` = t.`ID`
inner join (select PhotoId from PhotosTagsXref 
             LEFT JOIN `PhotosTags` AS t 
             ON pt.`TagId` = t.`ID`
             where (t.title = 'cond 1' or t.title = 'cond 2' ...)
             --where t.title in (list condition)    **this works as well**
             having count(1) = (count of conditions) ) filter
  on filter.photoID = pt.PhotoID
WHERE p.`Description` LIKE "%test%"
GROUP BY p.`ID`
ORDER BY p.`Created` DESC LIMIT 20

这应该有用,我对用于过滤器和连接的列做了一些假设,你可能需要重新设置...内部连接起到过滤器的作用,并且应该只提取匹配数相等的记录到提交的比赛总数。现在您只需要一种语言来插入这些条件和条件计数值。