我有例如两张桌子:
CREATE TABLE doc
( doc_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
, doc_text VARCHAR(10000) NOT NULL
);
CREATE TABLE doc_tag
( doc_id INT NOT NULL
, tag_word VARCHAR(50) NOT NULL
, PRIMARY KEY(doc_id, tag_word)
, KEY ix_doc_tag_word_doc_id (tag_word, doc_id)
);
表格doc中的记录可能包含以下内容: doc_tag
表中有5,10或甚至20个相关的单词标签。
如何在MYSQL
中编写存储过程,我可以为doc_id
记录提供doc
以及匹配标记字的最小数量(表doc_tag
)。结果应该是其他doc_id
个记录的doc
s,这些记录具有与BASE doc_tag
记录相同的最小字数(存储在doc
中)。
所以我的原始BASE doc
记录可能在doc_tag
表中有10个标记词,但我想查找共享10个标记词中至少5个的所有其他doc
记录在doc_tag
。只要属于BASE doc_tag
记录的doc
个字中至少有5个也可以在属于该doc_tag
记录的doc
个记录中找到,那10个匹配中的哪一个无关紧要。其他doc.doc_id
条记录。
一个例子:
基础:
doc_text
:1
doc_tag.doc_id
:"这是我的基础文件"
doc_tag.tag_word
:1,doc_tag.doc_id
:预订
doc_tag.tag_word
:1,doc_tag.doc_id
:表
doc_tag.tag_word
:1,doc_tag.doc_id
:主席
doc_tag.tag_word
:1,doc_tag.doc_id
:墙
doc_tag.tag_word
:1,doc_tag.doc_id
:floor
doc_tag.tag_word
:1,doc_tag.doc_id
:房子
doc_tag.tag_word
:1,doc_tag.doc_id
:电话
doc_tag.tag_word
:1,doc
:上限
匹配的其他doc.doc_id
记录:
doc_text
:20187年
doc_tag.doc_id
:"这是一个与其他文档匹配的标记"
doc_tag.tag_word
:20187,doc_tag.doc_id
:ceiling
doc_tag.tag_word
:20187,doc_tag.doc_id
:floor
doc_tag.tag_word
:20187,doc_tag.doc_id
:房间
doc_tag.tag_word
:20187,doc_tag.doc_id
:房子
doc_tag.tag_word
:20187,doc_tag.doc_id
:wall
doc_tag.tag_word
:20187,doc_tag.doc_id
:电话
doc_tag.tag_word
:20187,doc_tag.doc_id
:地下室
doc_tag.tag_word
:20187,doc
:走廊
记录匹配的原因是单词" ceiling"," floor"," house"," phone"和"墙"是SELECT REPLACE(FieldName ,';',',') FROM TableName
个记录的标记词。两者都有其他标记词没有共享并不重要。
可能需要准备代码来识别原始10个标记词中的5个的可能组合以创建最终查询。但是,我觉得有一种美丽而紧凑的方式可以做到这一点,这让我望而却步。
如果mySQL的存储过程语言没有配备来处理这个问题,请随意提出另一种方言的解决方案,例如: MSSQL的T-SQL。它主要是我会感兴趣使用的算法。
答案 0 :(得分:1)
尝试这样的事情:
SELECT OTHER.doc_id
FROM doc_tag BASE
INNER JOIN doc_tag OTHER ON BASE.doc_id <> OTHER.doc_id AND
BASE.tag_word = OTHER.tag_word
WHERE BASE.doc_id = @baseid
GROUP BY OTHER.doc_id
HAVING COUNT(*) >= @min_records
基本上,您正在获取基础文档的所有标记,过滤这些标记的所有其他实例,然后按文档ID对这些标记进行分组以获得计数。
答案 1 :(得分:0)
我想你想要一个group by
和having
条款:
select doc_id
from doc d join
doc_tag t
on d.doc_id = t.doc_id
group by doc_id
having count(*) >= 5;