mysql使用左外连接过滤结果

标签 mysql database filter left-join

我的查询:

        SELECT content.*, activity_log.content_id FROM content
        LEFT JOIN activity_log 
        ON content.id = activity_log.content_id 
        AND sess_id = '$sess_id'
        WHERE activity_log.content_id IS NULL
        AND visibility = $visibility
        AND content.reported < ".REPORTED_LIMIT."
        AND content.file_ready = 1
        LIMIT 1

该查询的目的是从内容表中获取用户未查看过的 1 行(由 session_id 标识),但它仍然返回已查看过的内容。怎么了? (我检查了表格以确保 content_ids 在那里)

注:我觉得这样比使用子查询更高效,思想?

最佳答案

问题显然出在您的 JOIN 条件中。当您对内部联接结果感兴趣时,您正在使用的优化(将条件应用于基表)很有意义,但如果是外部联接,则读取如下:查找 contentactivity_log 内容 ID 匹配且 session ID 匹配时的行,当内容 ID 的日志丢失或内容 ID 不丢失时返回 activity_log 行的空值,但是 session ID 不是指定的。这几乎不是您想要的。

您的查询应如下所示:

SELECT content.*, activity_log.content_id
FROM (
SELECT *
FROM content
WHERE sess_id = '$sess_id'
    AND visibility = $visibility
    AND file_ready = 1
    AND reported < ".REPORTED_LIMIT."
) as content
LEFT JOIN activity_log 
ON content.id = activity_log.content_id 
WHERE activity_log.content_id IS NULL
LIMIT 1;

如果性能不是最优的,可以考虑在(sess_id, visibility, fileready, reported)上创建复合索引。

关于mysql使用左外连接过滤结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2660552/

相关文章:

PHP 将一个变量的值拆分为多个变量

php - 如何在 PHP 中解码 json 字符串并添加到数组

ruby - 使用 Rails 安装程序安装后测试 sqlite3 的正确安装

Javascript:数组中的多个过滤器

mysql - 如何使用 Go 创建到 Cloud SQL 数据库的 TLS 连接?

php - 如何在 PHP 中显示 MySQL Select 语句结果

mysql - 我如何为 ALL 条件编写此 SQL 查询?

php - 构建 mysql 查询和/或 php 代码来关联不明确的数据点

java - 身份验证过滤器未加载 3 个网页的 css

Haskell - 过滤器类型类