sql - Postgres / SQL中是否有办法从字符串中的字符是列名的列中替换字符串中的字符?
问题描述
我有一张名为 的表sentences
,还有一张名为 的表logs
。
该sentences
表如下所示:
|------------|---------------------------------------|
| id | sentence |
|------------|---------------------------------------|
| 1 | [var1] says hello! |
|------------|---------------------------------------|
| 2 | [var1] says [var2]! |
|------------|---------------------------------------|
| 3 | [var1] says [var2] and [var3]! |
|------------|---------------------------------------|
| 4 | [var4] says [var2] to [var1]! |
|------------|---------------------------------------|
该logs
表如下所示:
|------------|------------------|--------------|--------------|--------------|--------------|
| id | sentenceId | var1 | var2 | var3 | var4 |
|------------|------------------|--------------|--------------|--------------|--------------|
| 1 | 1 | Sam | | | |
|------------|------------------|--------------|--------------|--------------|--------------|
| 2 | 2 | Joe | what's up | | |
|------------|------------------|--------------|--------------|--------------|--------------|
| 3 | 3 | Tim | hey | how are you | |
|------------|------------------|--------------|--------------|--------------|--------------|
| 4 | 4 | Joe | hi | | Tiffany |
|------------|------------------|--------------|--------------|--------------|--------------|
我试图得到的结果是:
|------------|-----------------------------------------|
| logs.id | sentences.sentence |
|------------|-----------------------------------------|
| 1 | [Sam] says hello! |
|------------|-----------------------------------------|
| 2 | [Joe] says [what's up]! |
|------------|-----------------------------------------|
| 3 | [Tim] says [hey] and [how are you]! |
|------------|-----------------------------------------|
| 4 | [Tiffany] says [hi] to [Joe] |
|------------|-----------------------------------------|
我不确定如何编写 SQL 查询以使数据库为我进行文本替换。
我可以使用内部连接从两个表中选择所有内容,然后在代码中循环并自己进行替换。IE:
SELECT logs.id, sentences.sentence, logs.var1, logs.var2, logs.var3, logs.var4 FROM logs INNER JOIN sentences ON logs.sentenceId = sentences.id
然后在代码中:
logs.forEach(log => log.sentence.replace(/\[(.*?)\]/g, ($matchedString, $columnName) => log[$columnName] ))
但如果可能的话,我希望数据库为我做这件事,这样我就不必选择比我需要的更多的数据。
解决方案
我会写一个函数来做到这一点:
create function replace_vars(p_sentence text, p_vars jsonb)
returns text
as
$$
declare
l_rec record;
l_result text;
begin
l_result := p_sentence;
for l_rec in select * from jsonb_each_text(jsonb_strip_nulls(p_vars)) as x(var,value)
loop
l_result := replace(l_result, l_rec.var, l_rec.value);
end loop;
return l_result;
end;
$$
language plpgsql;
然后你可以像这样使用它:
select s.id, s.sentence, replace_vars(s.sentence, to_jsonb(l)) new_sentence
from sentences s
left join logs l on l.sentenceid = s.id;
推荐阅读
- go - 转换为 DataResponse 的参数过多
- sql - 如何在 SQL 中对一组自定义计算字段求和?
- intellij-idea - 如何打开在 Intellij 中导出的图表?
- mongodb - 是否有任何标准工具可以在启动期间使用 Spring Boot 更新 MongoDB 集合?
- javascript - ReactJs:由于不推荐使用componentWillMount,如何在组件安装之前执行代码?
- excel - 如何让我的代码在任何工作表上运行
- apache-kafka - Apache Camel Kafka:如何在生产者配置中设置属性“delivery.request.ms”
- graphql - GraphQL 无法查询字段“childImageSharp”,尽管该字段在 graphiql 上可用
- java - websocket - javax.net.ssl.SSLException:收到致命警报:handshake_failure
- python - AttributeError: 'tuple' 对象没有属性 'tag_name'