我有两个表构成文章内容的全文索引以供搜索。其中一个表只是与单词关联的主键,而另一个表记录它发生的文章及其在文档中的位置。可以想象,单个单词可以在具有不同位置的同一文档中多次出现,因此在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餐厅是大型餐厅中最好的餐厅之一 您可以在县里享用最好的土耳其美食。
因此,词条表在被应用程序调整以排除停用词后,其词汇表行中将包含Bob
,Restaurant
,finest
,greater
, county
,enjoy
,Turkish
和cusine
。 (我正在使用这个实际的文章,因为它是集合中的第一个,所以ids实际上从整数1开始。
@Mark Bannister提供的查询生成此结果集: 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个出现行。
答案 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(,)函数,因此这有点推测!)