mysql - 多次使用 LEFT JOIN 只带来 1 行

标签 mysql sql join left-join outer-join

它是一个智能标签库图像搜索系统。用户在这样的表中添加带有适当标签的图像:

image (id, title, ...)
tag (id, title) /* It doesn't matter who has created the tag*/
imagetag (image_id, tag_id) /* One image may have multiple tags */

用户查看图像和来自*这些图像标签* 的访问记录在usertagview 表中。 (请注意,我为此目的使用了 INSERT ON DUPLICATE UPDATE 查询。)

usertagview (user_id, tag_id, view_count)

现在请考虑一些带有以下标签的图像:

  • riverday(这是一张在晴天显示河流的图片)
  • rivernight(午夜月光下的那条河)
  • 夜晚

用户搜索标签river,所有带有river标签的图像都会显示:在这种情况下,第一张图像(标记为river day) 和第二个(由 river night 标记)显示。用户查看第二张图片(由rivernight 标记)并将查看记录在表usertagview 中。

然后用户尝试重新搜索标签 tree 并查看 tree night 图像。

我希望如果用户搜索 flower,则 flower night 优先于 flower day。我的意思是 flower night 应该在 flower day 之前。换句话说,我想要一个查询,根据用户之前的 View 列出由 flower 标记的图像。 (首先是花之夜,然后是其他)。

我的查询失败了:

SELECT

    DISTINCT (image.id) AS image_id,
    image.title AS image_title,
    SUM(usertagview.view_count) AS SUM_of_all_tag_views_for_each_image

FROM (image)

JOIN imagetag ON imagetag.image_id = image.id

**LEFT JOIN** usertagview ON
    usertagview.tag_id = imagetag.tag_id
    AND usertagview.user_id = {$user_id_from_php}

WHERE

    imagetag.tag_id IN ( {impolde(',', $array_of_id_of_tags_that_the_user_has_entered)} )
    AND
    usertagview.tag_id IN
        (SELECT tag_id FROM imagetag WHERE userimagetag.image_id = image.id)

ORDER BY SUM_of_all_tag_views_for_each_image DESC

问题

我查询中的 **LEFT JOIN** 与普通的 INNER JOIN 没有区别吗>。他们都有相同的结果。即使我使用 RIGHT JOIN 也没有区别。

最佳答案

您的 left joininner join 表现相同的原因是因为您在您的 left join 中有额外的条件where 子句。这实质上将您的外部联接变成了内部联接

之所以这样是因为如果usertagview.tag_idNULL的情况下没有匹配记录,你的IN语句在您的 WHERE 子句消除了具有 NULL 值的行。

要更正此问题,您可以将 usertagview.tag_id IN ... 检查到您的联接的 ON 子句中。

但是,这只是您问题的一半。您只是检查用户输入的特定标签的 View ,但如果我了解您的实际要求,您想要检查 View 中是否有与任何图像相关联的任何标签,这些标签的标签与您的搜索词匹配.

例如,当用户输入 flower 时,您希望首先找到任何带有 flower 标签的图像,然后检查所有其他标签的 View 一组图像。

我相信以下查询可以完成此操作,并且 this SQL Fiddle shows the query in action :

SELECT
  i.id AS image_id,
  i.title AS image_title,
  IFNULL(SUM(utv.view_count), 0) AS associated_view_totals
FROM
  imagetag originalTag
  JOIN imagetag associatedTags 
    ON associatedTags.image_id = originalTag.image_id
  JOIN image i 
    ON i.id = associatedTags.image_id
  LEFT JOIN usertagview utv 
    ON utv.user_id = 1
    AND utv.tag_id = associatedTags.tag_id
WHERE
  -- User searches for flower tag (Let's assume 5 == flower)...
  originalTag.tag_id IN (5)
GROUP BY
  i.id,
  i.title
ORDER BY 
  associated_view_totals DESC

关于mysql - 多次使用 LEFT JOIN 只带来 1 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10393872/

相关文章:

php - SELECT JOIN MySQL 查询中一列的唯一值

mysql - 如何打破用于连接其他表以获取其他数据的第一列中的数据

PHP + MySQL - 事务不回滚

mysql - 当值存储在另一个 ROW 中时使用 IN 的 SQL

java - Android sqlite数据库报错SQLiteException no such column

mysql - SQL - 查询关联 3 个不同的表和一个弱实体

mysql - 尝试获取查询中利润最高的酒店房间

java - HQL查询——通过连接关系拉取数据

mysql - HibernateCriteria 用 OR where 子句左连接

带连接的 Spring Data @Query