我正在尝试选择在另一个表中没有特定值的项目,我能够通过使用子查询来实现我想要的结果,但是它非常慢,所以我想知道是否可以采取不同的做法...
SELECT
content.*,
(SELECT views
FROM content_views
WHERE content_views.content = content.record_num
) as views
FROM content
RIGHT JOIN watch_log ON content.record_num = watch_log.content
WHERE content.enabled = 1
AND 24 NOT IN
(SELECT niche
FROM content_niches
WHERE content_niches.content = content.record_num
)
ORDER BY content.encoded_date
DESC LIMIT 0,6
我尝试使用 LEFT OUTER JOIN,但无法获得相同的结果...
SELECT
content.*,
(SELECT content_views.views
FROM content_views
WHERE content_views.content = content.record_num
) as views
FROM content
RIGHT JOIN watch_log ON content.record_num = watch_log.content
LEFT OUTER JOIN content_niches ON content.record_num = content_niches.content AND content_niches.niche = 24
WHERE content.enabled = 1
ORDER BY content.encoded_date
DESC LIMIT 0,6
最佳答案
混合左外连接和右外连接只是令人困惑。事实上,右连接
并不是真正需要的。通常可以用左连接
代替。在您的情况下,它可以被内部联接替换,因为 where
子句将其转换为内部联接。那么,怎么样:
SELECT c.*,
(SELECT views
FROM content_views cv
WHERE cv.content = c.record_num
) as views
FROM content c JOIN
watch_log wl
ON c.record_num = wl.content
WHERE c.enabled = 1 AND
NOT EXISTS (SELECT 1
FROM content_niches cn
WHERE cn.content = c.record_num AND
cn.niche = 24
)
ORDER BY c.encoded_date DESC
LIMIT 0, 6;
为了提高性能,您需要索引:content(enabled,encoded_date,record_num)
、content_views(content,views)
和content_niches(content,niche)
.
注释:
- 不要混合使用不同类型的外连接,除非您真的非常了解它们在做什么。
- 使用表名称缩写的表别名。这使得查询更容易编写和阅读。
- 无论您对格式的偏好如何,都不要在查询中以
DESC
(或ASC
)开始一行;这是ORDER BY
的修饰符。 NOT EXISTS
比NOT IN
更好。前者按照您期望的方式处理 NULL 值。如果存在NULL
值,后者不会返回任何内容。
关于mysql - 选择在另一个表中没有特定值的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35272586/