我有这种情况:
我想查看特定的字词,如果它们匹配一个字词,我将不得不更新该页面的内容并将其链接到该字词。但是现在我专注于获取内容页面,其中部分内容与特定术语相同。
这是我需要做的事情的想法,但它不起作用,因为子查询返回多个字段。
我想找到WHERE m.module_content类似于我所拥有的任何条款,但它应该全部检查。
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
JOIN terms t ON m.module_termid = t.term_id
WHERE m.module_content LIKE '%' || (SELECT term_name FROM terms) || '%'
module_content包含html格式的文本,所以我最终需要做的是,如果它与一个术语匹配而且它还不是链接,我将添加一个指向该特定术语的链接。
这里最好的选择是什么? (我使用的是mysql btw)
为您举例说明预期结果:
条款:id:1,名称:hello 模块:id:1,内容:< p> Hello World< / p>
我想提出id为1的模块,因为它包含某个地方的名称为“hello”的内容
更新:
尝试过Pablo的解决方案,但这就是:
例如,“雷戴维斯”与“浮动”一词无关,所以不应该出现。
答案 0 :(得分:5)
我认为您只需要将JOIN
条件更改为:
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
JOIN terms t ON (m.module_content LIKE '%' || t.term_name || '%')
话虽如此,这可能是非常低效的。请考虑使用 FULL TEXT INDEX INSTEAD 进行此操作。
答案 1 :(得分:4)
经过一番研究,我的解决方案看起来像这样:
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
INNER JOIN terms t ON m.module_termid = t.term_id
WHERE m.module_content LIKE CONCAT('%', TRIM(t.term_name), '%')
编辑:关于Paul Morgans的评论,我将CONCAT('%', t.term_name, '%')
替换为CONCAT('%', TRIM(t.term_name), '%')
,以便删除t.term_name中的所有空格。如果您需要t.term_name中的空格,只需删除TRIM
调用并使用旧版本(CONCAT('%', t.term_name, '%')
)
答案 2 :(得分:2)
MySQL没有任何连接运算符,查询实际应该写为:
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
JOIN terms t ON m.module_content LIKE CONCAT('%', t.term_name, '%');
但是发生了什么:
m.module_content LIKE '%' || t.term_name || '%'
实际上相当于
(m.module_content LIKE '%') || (t.term_name) || ('%')
总是1.因此,你有一个笛卡儿积=)
UPD :作为对自己的引用,MySQL确实有一个连接运算符||
,但要使用它,应该设置PIPES_AS_CONCAT模式:
mysql> SET sql_mode= 'pipes_as_concat';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT 'qwe' || 'asd';
+----------------+
| 'qwe' || 'asd' |
+----------------+
| qweasd |
+----------------+
1 row in set (0.00 sec)
答案 3 :(得分:1)
您可以尝试这样做:
SELECT m.module_termid, t.term_name, m.module_name, m.module_content
FROM modules m
JOIN terms t ON (m.module_content LIKE '%' + t.term_name + '%')
答案 4 :(得分:1)
使用“IN”代替“LIKE”应该是解决方案:类似于: -
SELECT m.module_termid,t.term_name,m.module_name,m.module_content
FROM modules m JOIN terms t ON m.module_termid = t.term_id
在哪里m.module_content IN (SELECT term_name FROM terms);
答案 5 :(得分:0)
尝试以下查询 -
SELECT
tp.module_termid,
tp.term_name,
tp.module_name,
tp.module_content
FROM (
SELECT
m.module_termid,
t.term_name,
m.module_name,
m.module_content,
IF(LOCATE(t.term_name,m.module_content)!=0, m.module_content, ' ')
as required_content
FROM modules m
LEFT JOIN terms t ON m.module_termid = t.term_id
) tp
WHERE tp.required_content != '';
对于上面的查询,您将获得模块表的module_content列中term_name列数据作为整个单词存在的所有行。如果你不想只对整个单词进行匹配,那么在这种情况下你可以使用MYSQL的正则表达式函数来代替LOCATE函数。
LOCATE 功能的文档可以在here
中找到答案 6 :(得分:0)
我不认为这是一个解决问题的好方法,比如this.supports你有很多模块项,而且流行的词是limit.each你执行sql的时候,它需要大量的磁盘io并可能阻止在线mysql数据库。 我的方式是这样的:
正如你所看到的那样。它非常高效和快速。因此,问题是如何对模块内容进行反向索引。sphinx将做得很好。 希望这会对你有所帮助:)。