2010-11-11 67 views
2

这是与我的最后一个问题mysql query with AND, OR and NOTMySQL有所有值

而不是编辑的问题,我问一个新的,因为这个问题是一个改变前一个问题的一部分。

我期待做一个mysql查询,返回所有需要的主题的文章。

Article 
    id 
    .... 

Topic 
    id 
    .... 

ArticleTopics 
    article_id 
    topic_id 
    type 

东西,将有效地做到:

SELECT * FROM Article LEFT JOIN ArticleTopics ON Article.id = ArticleTopics.article_id 
WHERE ArticleTopics.topic_id HAS ALL (these topics) 

这可能吗?什么是最好的方法呢?

回答

3

一些其他的答案建议使用对每个筛选子句的子表的别名 - 这可能不是非常有效或很好地扩展。

考虑:

SELECT x.* 
FROM Article x INNER JOIN 
(SELECT t.article_id, COUNT(t.article_id) 
    FROM articleTopics t 
    WHERE t.topic_id IN ([your_list_of_topics]) 
    GROUP BY t.article_id 
    HAVING COUNT(t.article_id)>=[number of elements in [your_list_of_topics]] 
    ORDER BY COUNT(t.article_id) DESC 
    LIMIT 0,100) AS ilv 
ON x.id=ilv.article_id 

这种方法的另一个优点是,查询的结构不需要与您正在搜索的主题数改变 - 你甚至可以把它们放在一个临时表并执行连接而不是使用'IN(...)'文字。

您需要试试看哪个查询的行为更好。

+0

谢谢你是完美的!我的工作很棒。现在我需要添加额外的东西,以便它添加NOT和OR到问题中看到我的上一个问题http://stackoverflow.com/questions/4153137/mysql-query-with-and-or-and-not – Lizard 2010-11-11 15:13:50

+0

所以你知道,它作为一个字符串,而不是一个子查询更好地工作 – Lizard 2010-11-11 16:17:18

+0

哇!这是一个很好的方法!我真的很好奇,与多个INNER JOIN相比,'WHERE IN'对索引有多快。如果MySQL对事情做得很好,差别不应该那么大,它基本上是相同的查找操作。 – 2010-11-15 09:16:26

1

这是通过使用具有相同表格的多个连接完成的。

要选择具有ID 1,2和3话题的所有文章,你需要做的:

SELECT * FROM Article a 
    INNER JOIN ArticleTopics at1 ON a.id = at1.article_id AND at1.topic_id = 1 
    INNER JOIN ArticleTopics at2 ON a.id = at2.article_id AND at2.topic_id = 2 
    INNER JOIN ArticleTopics at3 ON a.id = at3.article_id AND at3.topic_id = 3 

//编辑 固定它。添加了表别名;我必须一直有良好的ORM解决方案太久...

+0

请让我们知道这个解决方案是否工作!我写得有点快,可能犯了一个错误。随时举报,我会尽力解决它。 – 2010-11-11 10:38:35

+0

SQL错误:1066:不是唯一表/别名:'ArticleTopics' – Lizard 2010-11-11 10:46:37

+0

对不起,已更新它。再看一眼! – 2010-11-11 12:46:54

0
SELECT 
    * 
FROM 
    Article 
WHERE 
    (SELECT COUNT(*) FROM ArticleTopics 
     WHERE Article.id = ArticleTopics.article_id AND 
     ArticleTopics.topic_id=1) > 0 AND 
    (SELECT COUNT(*) FROM ArticleTopics 
     WHERE Article.id = ArticleTopics.article_id AND 
     ArticleTopics.topic_id=2) > 0 AND 
    (SELECT COUNT(*) FROM ArticleTopics 
     WHERE Article.id = ArticleTopics.article_id AND 
     ArticleTopics.topic_id=3) > 0 AND 
    ... 
+0

如果我可以评论,这个查询必须在整个表上执行相当多的COUNT操作,这可能会使其在大型数据集上变得非常缓慢。 (我不认为MySQL优化count()> 0)。我想,查找会更有效率。 – 2010-11-11 12:45:23

+0

好吧,我认为最终你会以同样的方式在每个解决方案中扫描整个表格。 MySQL大师需要:) – 2010-11-11 13:06:20