MySQL连接计数来自一个表,其中一个来自另一个表

时间:2011-11-25 16:51:04

标签: mysql left-join

我有两个表构成文章内容的全文索引以供搜索。其中一个表只是与单词关联的主键,而另一个表记录它发生的文章及其在文档中的位置。可以想象,单个单词可以在具有不同位置的同一文档中多次出现,因此在word_locations表中可以多次出现相同的单词id。

以下是结构:

词:

id          bigint
word        tinytext

word_location:

id          bigint(20)  
wordid      bigint(20)  
location    int(11) 
article_id  int(11)

我需要编写的是一个查询,它将查找任何一个配置文件的每个单词的出现次数。我需要为完全没有出现的wordid保留零值,所以我认为这需要是一个左连接。但是,每当我尝试添加where查询来限制文章时,任何根本没有出现的wordid都不会包含在结果集中。

我试过了:

select words.wordid, COUNT(word_location.wordid) as appears from words left join word_location on word.id = word_location.wordid where article_id = %s GROUP BY wordid

但是这个查询不会为完全没有出现的单词返回零。

如何修改此左连接?

提前致谢!

修改

以下是不同查询的示例数据集和结果集。

示例文章内容:

  

Bob's餐厅是大型餐厅中最好的餐厅之一   您可以在县里享用最好的土耳其美食。

因此,词条表在被应用程序调整以排除停用词后,其词汇表行中将包含BobRestaurantfinestgreatercountyenjoyTurkishcusine。 (我正在使用这个实际的文章,因为它是集合中的第一个,所以ids实际上从整数1开始。

@Mark Ba​​nnister提供的查询生成此结果集: wordid - word - occurrence出现:

128 clifton 0
1   bob's   2
2   restaurant  2
3   one 1
4   finest  3
5   restaurants 2
6   greater 1
9   county  1
12  enjoy   3
13  turkish 6
14  cuisine 1

结果集本身是正确的 - 但是id 128根本没有出现在文档中,并且是结果集中唯一出现0的东西。目标是返回整个词汇表中的出现次数文件(这大约是2500个不同的词)

我在上面编辑之前的原始问题查询实际上返回了相同的结果集,但根本没有任何0个出现行。

3 个答案:

答案 0 :(得分:3)

您需要在加入条件中包含您的文章选择:

select words.wordid, COUNT(word_location.wordid) as appears 
from words 
left join word_location on word.id = word_location.wordid and article_id = ? 
GROUP BY wordid

在WHERE子句中包含对article_id的限制有效地将左连接转回到内连接。

答案 1 :(得分:1)

我会使用subselect而不是join。

SELECT words.id, (SELECT count(*) FROM word_location WHERE word_location.wordid = words.id) as appears

答案 2 :(得分:0)

有点猜测这个,但我认为COUNT()只是忽略你的空值,而不是计算它们并到达0.(NULL + NULL!= 0)

查看IFNULL()函数,您可以执行以下操作:

COUNT(IFNULL(word_location.wordid, 0))

(免责声明 - 我更习惯于Oracle的NVL(,)函数,因此这有点推测!)