我有一个包含列和数据的表“文章”:
article_id title body
1 This is the title This is the body text
2 Another title Another body text
另一个包含列和数据的表“类别”:
category_id category
1 localnews
2 visible
3 first10
包含列和数据的表“类别”:
categories_id article_id category_id
1 1 1
2 1 2
3 1 3
4 2 1
5 2 3
我想选择行,其中categories.category_id = 1 AND = 2 AND = 3
我正在使用:
SELECT articles.article_id, articles.title, articles.body,
categories.article_id, categories.category_id
FROM articles, categories
WHERE articles.article_id = categories.article_id
AND categories.article_id = 1
AND categories.article_id = 2
AND categories.article_id = 3
但它不起作用。显然mySQL需要另一种语法。 有人可以帮忙吗? 感谢
答案 0 :(得分:3)
SELECT
Articles.article_id,
COUNT( Categories.article_id ) AS total
FROM CategoryArticles
LEFT JOIN Articles USING (article_id)
WHERE
CategoryArticles.category_id IN (1,2,3)
GROUP BY CategoryArticles.article_id
HAVING total = 3
我在表格中使用了一些不同的名称,因为在您的示例中,category
和categories
之间的区别很难被注意到。
答案 1 :(得分:1)
行的列不能同时为1,2或3 ,这是AND
规定的内容。在OR
条件下使用WHERE
。更好 - 为了便于阅读 - 您可以使用IN
:
SELECT ...
WHERE `categories`.`article_id` IN(1,2,3)
答案 2 :(得分:1)
除了常用的IN()和使用HAVING计数之外,我还会对多重连接的性能差异感兴趣,如下所示......
SELECT STRAIGHT_JOIN
articles.article_id,
articles.title,
articles.body
FROM
categories c1
JOIN articles
on c1.article_id = articles.article_id
JOIN categories c2
on c1.article_id = c2.article_id
AND c2.category_id = 2
JOIN categories c3
on c1.article_id = c3.article_id
AND c3.category_id = 3
WHERE
c1.Category_ID = 1
是的,这可能看起来很模糊,但让我们考虑一下......通过在类别表上进行联接FIRST,其中您的一个特定类别 - 首先来自类别的实例应该代表具有哪个类别的类别最小的粒度。例如:您的本地新闻,可见和第一的类别10.本地新闻可能会拥有最多的条目,而Visible和First 10甚至更少......那些甚至会有最少数量的记录。使用此类别作为where子句。
所以,你说你有10万篇文章,其中90,000篇是本地新闻,45,000篇是Visible,12,000篇是第10篇。通过仅查看12,000篇文章,你就可以消除大部分数据。
然后加入文章表,并根据其他条件将AGAIN分类为别名C2和C3,如果找到,已完成,如果没有,则将其排除。
同样,我想知道性能影响。我也会在类别表上有一个复合索引(article_id,category_id)
答案 3 :(得分:0)
值不能同时为全部三个值,因此您最好使用IN
中的WHERE
子句来定义要返回的值。给你已经有一个连接条件,你也想把它移到ON
子句中;即:
SELECT articles.article_id, articles.title, articles.body, categories.article_id, categories.category_id
FROM articles
INNER JOIN categories ON articles.article_id = categories.article_id
WHERE categories.article_id IN ( 1, 2, 3 )
当然,您可以进入下一步并执行:
SELECT articles.article_id, articles.title, articles.body, category.category
FROM articles
INNER JOIN categories ON articles.article_id = categories.article_id
INNER JOIN category ON categories.category_id = category.category_id
WHERE categories.article_id IN ( 1, 2, 3 )
如果您只想展示出现在所有三个类别中的文章,那么您可以采取以下方法:
SELECT articles.article_id, articles.title, articles.body
FROM articles
INNER JOIN categories AS c1
ON articles.article_id = c1.article_id
AND c1.category_id = 1
INNER JOIN categories AS c2
ON articles.article_id = c2.article_id
AND c2.category_id = 2
INNER JOIN categories AS c3
ON articles.article_id = c3.article_id
AND c3.category_id = 3