替换 select 结果中所有出现的子查询
Replace all occurrences of subquery in select result
正在从 MySQL 中的 Sparx EA 数据库导出数据。
数据库包含有注释的对象
select o.Note from t_object o
结果可能是
Note
Contains reference to term1 and term2
Another note that mentions term1 only
A note that doesn't mention any terms
还有个词汇表可以这样查询
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;%'
本次查询的结果
TERM
term1
term2
要求是我在第一个查询的注释中的每个单词下划线,这些单词与第二个查询中的一个术语完全匹配。可以通过将单词括在 <u>
</u>
标签
中来添加下划线
所以最终的查询结果应该是
Note
Contains reference to <u>
term1</u>
and <u>
term2</u>
Another note that mentions <u>
term1</u>
only
A note that doesn't mention any terms
有没有办法在 select 查询中执行此操作? (所以没有变量、临时表、循环和所有这些东西)
在这里,我将 t_object
table 的 t_glossary
table 列中的所有 TERM
替换为 <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('%' , g.TERM , '%') and CTE.note2 not like concat('%<u>', g.term , '</u>%')
)
SELECT DISTINCT note2, note, level
FROM CTE
WHERE level =
(SELECT MAX(level) FROM CTE c WHERE CTE.note = c.note)
输出:
note2
note
level
A note that doesn't mention any terms
A note that doesn't mention any terms
0
Another note that mentions <u>term1 </u> only
Another note that mentions term1 only
1
Contains reference to <u>term1 </u> and <u>term2</u>
Contains reference to term1 and term2
2
db<>fiddle here
我认为正则表达式可能是更好的方法。对于您的示例,您需要:
select regexp_replace(note, '(term1|term2)', '<u></u>')
from t_object;
您可以在 MySQL 中轻松地将其构建为:
select regexp_replace(note, pattern, '<u></u>')
from t_object cross join
(select concat('(', group_concat(term separator '|'), ')') as pattern
from t_glossary
) g;
Here 是一个 db<>fiddle.
正则表达式有一个关键优势,那就是它们可以让您更灵活地处理单词边界。以上替换了任何出现的术语,无论周围的字符如何。但是您可以使用正则表达式的强大功能对其进行调整。
我可能还建议可以在应用程序层使用正则表达式来完成这种替换。
正在从 MySQL 中的 Sparx EA 数据库导出数据。
数据库包含有注释的对象
select o.Note from t_object o
结果可能是
Note |
---|
Contains reference to term1 and term2 |
Another note that mentions term1 only |
A note that doesn't mention any terms |
还有个词汇表可以这样查询
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;%'
本次查询的结果
TERM |
---|
term1 |
term2 |
要求是我在第一个查询的注释中的每个单词下划线,这些单词与第二个查询中的一个术语完全匹配。可以通过将单词括在 <u>
</u>
标签
所以最终的查询结果应该是
Note |
---|
Contains reference to <u> term1</u> and <u> term2</u> |
Another note that mentions <u> term1</u> only |
A note that doesn't mention any terms |
有没有办法在 select 查询中执行此操作? (所以没有变量、临时表、循环和所有这些东西)
在这里,我将 t_object
table 的 t_glossary
table 列中的所有 TERM
替换为 <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('%' , g.TERM , '%') and CTE.note2 not like concat('%<u>', g.term , '</u>%')
)
SELECT DISTINCT note2, note, level
FROM CTE
WHERE level =
(SELECT MAX(level) FROM CTE c WHERE CTE.note = c.note)
输出:
note2 | note | level |
---|---|---|
A note that doesn't mention any terms | A note that doesn't mention any terms | 0 |
Another note that mentions <u>term1 </u> only | Another note that mentions term1 only | 1 |
Contains reference to <u>term1 </u> and <u>term2</u> | Contains reference to term1 and term2 | 2 |
db<>fiddle here
我认为正则表达式可能是更好的方法。对于您的示例,您需要:
select regexp_replace(note, '(term1|term2)', '<u></u>')
from t_object;
您可以在 MySQL 中轻松地将其构建为:
select regexp_replace(note, pattern, '<u></u>')
from t_object cross join
(select concat('(', group_concat(term separator '|'), ')') as pattern
from t_glossary
) g;
Here 是一个 db<>fiddle.
正则表达式有一个关键优势,那就是它们可以让您更灵活地处理单词边界。以上替换了任何出现的术语,无论周围的字符如何。但是您可以使用正则表达式的强大功能对其进行调整。
我可能还建议可以在应用程序层使用正则表达式来完成这种替换。