不要误会我的意思,但你已经为自己设置了一个受伤的世界。最好的方法是遵循 lonesomeday 的建议,并在插入时解析主题标签。这也大大减少了处理时间并使其更具确定性(工作负载在插入之间“分散”)。
如果你想继续,你需要解决几个问题。
1) 识别标签。
2) 多选标签。如果您有一条消息说“#MySQL 拆分是#cool”,您希望从一条消息中获取 两 行,一条是“MySQL”,另一条是“cool”。
3) 选择合适的消息
4) 表演
您至少可以通过两种方式解决此问题。您可以使用 stored function ,您可以找到 here on SO(实际上来自 this site) - 不过您必须对其进行修改。
此语法将使您在value 中第一次出现#hashtag 加上它后面的所有文本:
select substring(value, LENGTH(substring_index(value, '#', 1))+1);
然后,您需要确定每个#hashtag 的#stops 位置。 (它可以是#parenthesized)。此时,您需要一个正则表达式,或搜索至少一个字母数字字符的序列 - 用正则表达式的说法,[a-zA-Z0-9]+ - 通过指定所有可能的字符或使用循环,即“#”是可以的,“#t " 可以,"#ta" 可以,"#tag" 可以,"#tag" 不行,所以你的标签是'#tag'(或'tag')。
另一种更有前途的方法是使用用户定义函数来捕获主题标签;你可以使用PREG_CAPTURE。
您可能必须合并这两种方法:修改存储函数的设置和内部循环以读取
DECLARE cur1 CURSOR FOR SELECT messages.messagetext
FROM messages
WHERE messages.messagetext LIKE '%#%';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DROP TEMPORARY TABLE IF EXISTS table2;
CREATE TEMPORARY TABLE table2( hashtag` VARCHAR(255) NOT NULL
) 引擎=内存;
...
SET occurrence = (SELECT LENGTH(msgtext)
- LENGTH(REPLACE(msgtext, '#, ''))
+1);
SET i=1;
WHILE i <= occurrence DO
INSERT INTO table2 VALUES SELECT PREG_CAPTURE('/#([a-z0-9]+)/i', messagetext, occurrence));
SET i = i + 1;
END WHILE;
...
这将返回一个消息 ID 和主题标签列表。然后你需要GROUP他们BY标签,计数他们和ORDER计数DESC,最后添加LIMIT 5,只得到五个最受欢迎的。