替换选择结果中所有出现的子查询

问题描述

正在从 MysqL 中的 Sparx EA 数据库导出。

数据库包含有笔记的对象

select o.Note from t_object o

结果可能是

注意
包含对 term1 和 term2 的引用
一个只提到 term1 的注释
未提及任何条款的注释

还有一个词汇表,我可以这样查询

select g.TERM 
  from t_glossary g
 union
select o.Name 
  from t_diagram d
  join t_diagramobjects dgo 
    on dgo.Diagram_ID = d.Diagram_ID
  join t_object o 
    on o.Object_ID = dgo.Object_ID
where 1=1
   and d.styleEx like '%MDGDgm=Glossary Item Lists::GlossaryItemList;%' 

本次查询的结果

期限
term1
term2

要求我在第一个查询的注释中与第二个查询中的一个术语完全匹配的每个单词下划线。可以通过将单词括在 <u> </u> 标签

中来完成下划线

所以最终的查询结果应该是

的引用
注意
包含对 <u>term1</u><u>term2</u>
另一条仅提及<u>term1</u>
未提及任何条款的注释

有没有办法在 select 查询中做到这一点? (所以没有变量、临时表、循环和所有这些东西)

解决方法

在这里,我已将 TERM 表中 t_glossary 列中 note 表中的所有 t_object 替换为 <ul>Term</ul>

架构:

 create table  t_object(note varchar(500));
 insert into t_object                                    
   select 'Contains reference to term1 and term2' as Note
   union all
   select 'Another note that mentions term1 only'
   union all
   select 'A note that doesn''t mention any terms';
 
                                     
 create table t_glossary (TERM varchar(500));
 insert into t_glossary 
 select 'term1 '
 union all
 select 'term2';

查询:

 WITH  recursive CTE (note,note2,level)  AS
 (
     SELECT note,note,0 level
     FROM   t_object
 
     UNION ALL
 
     SELECT CTE.note,REPLACE(CTE.note2,g.TERM,concat(' <u>',g.term,'</u> ')),CTE.level + 1
     FROM   CTE
     INNER JOIN t_glossary g ON CTE.note2 LIKE concat('%','%') and CTE.note2 not like concat('%<u>','</u>%')
         
 )
 SELECT DISTINCT note2,level
 FROM CTE
 WHERE level =
     (SELECT MAX(level) FROM CTE c WHERE CTE.note = c.note)

输出:

的注释 的引用
note2 注意 level
未提及任何术语的注释 未提及任何术语的注释 0
另一个只提到term1 另一个只提到 term1 的注释 1
包含对term1 term2 包含对 term1 和 term2 的引用 2

dbfiddle here

,

我认为正则表达式可能是更好的方法。对于您的示例,您需要:

select regexp_replace(note,'(term1|term2)','<u>$1</u>')
from t_object;

您可以在 MySQL 中轻松地将其构造为:

select regexp_replace(note,pattern,'<u>$1</u>')
from t_object cross join
     (select concat('(',group_concat(term separator '|'),')') as pattern
      from t_glossary
     ) g;

Here 是一个 dbfiddle。

正则表达式有一个关键优势,它们可以让您在单词边界上具有更大的灵活性。以上替换了任何出现的术语,无论周围的字符如何。但是您可以使用正则表达式的强大功能进行调整。

我也可能建议在应用层使用正则表达式来完成这种替换。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...