【问题标题】:find and replace from table从表中查找和替换
【发布时间】:2020-05-07 18:40:45
【问题描述】:

我有带有一些文本的 table_A,我需要从 table_b 中选择一个新文本并替换 table_a

这是table_a

select 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. {T3} Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. {T1} Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. {T2} Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. {T4} Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'::text as textvalue

这是table_b

select '{T1}' as find, 'Test 1a Test 1b Test 1c' as newvalue
union all
select '{T2}' as find, 'Test 2a Test 2b Test 2c' as newvalue
union all
select '{T3}' as find, 'Test 3a Test 3b Test 3c' as newvalue
union all
select '{T4}' as find, 'Test 4a Test 4b Test 4c' as newvalue
order by find

到目前为止我做了什么但没有成功:

select z.newtextvalue
from
(select t2.find, t2.newvalue, t1.textvalue, replace(lag(replace(t1.textvalue,t2.find,t2.newvalue)) over(order by t2.find),t2.find,t2.newvalue) as newtextvalue
from
(select 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. {T3} Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. {T1} Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. {T2} Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. {T4} Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'::text as textvalue) as t1,
(select '{T1}' as find, 'Test 1a Test 1b Test 1c' as newvalue
union 
select '{T2}' as find, 'Test 2a Test 2b Test 2c' as newvalue
union 
select '{T3}' as find, 'Test 3a Test 3b Test 3c' as newvalue
union 
select '{T4}' as find, 'Test 4a Test 4b Test 4c' as newvalue
order by find) as t2) as z
order by z.find desc limit 1

糟糕的结果:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。 测试 3a 测试 3b 测试 3c Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat。 {T1} 杜伊斯 aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur。 {T2} 例外 sint occaecat Cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est 实验室。 测试 4a 测试 4b 测试 4c Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labare et dolore magna aliqua。

以及预期的结果:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。 测试 3a、测试 3b、测试 3c Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat。 Test 1a, Test 1b, Test 1c Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla 偏执。 Test 2a, Test 2b, Test 2c Exceptioneur sint occaecat cupidatat non proident, sunt in 过失 qui officia deserunt mollit anim id est labourum。 测试 4a、测试 4b、测试 4c Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。

欢迎任何建议/更正!

【问题讨论】:

  • 我是格鲁特。你能想出一个更短、更易读的例子吗?
  • @LaurenzAlbe,我试图总结一下,但网站强迫我详细说明,否则我无法发布。无论如何,我在表B中有索引和new_text,我想在表A中搜索与表B中的索引匹配的文本部分并将其替换为表B中的文本,清楚吗?
  • 示例很好,但请使用较短的文字。
  • 您的LAG() 只会考虑前一行。所以对于{T4},你只会看到{T4} 和你的LAG() {T3}。删除您的LIMIT 1。相反,您可能需要在此处使用递归 CTE,以便您可以迭代每个查找/替换并更新字符串。

标签: postgresql postgresql-11


【解决方案1】:

扩展我的评论。因为LAG() 只会考虑T2 表中的当前行和前一行,所以它只能对两行执行查找和替换。您的 order bylimit 正在获取 {t4} 和(来自您的滞后){t3} 的替换,并删除结果(记录 2 和 3),其中 {t1} 和/或 {t2} 替换在范围内.

相反,您可以在遍历所有令牌时递归地查找和替换 T2 表。

考虑:

WITH RECURSIVE fandr AS
(
    SELECT replace(t1.textvalue, t2.find, t2.newvalue) as textvalue, find as found, findorder
    FROM t1, t2
    WHERE t2.findOrder = 1
    UNION ALL
    SELECT replace(fandr.textvalue, t2.find, t2.newvalue) as textvalue, t2.find, t2.findorder
    FROM fandr, t2
    WHERE t2.findOrder = fandr.findorder + 1
)
, t2 AS
(
    select 1 as findorder, '{T1}' as find, 'Test 1a Test 1b Test 1c' as newvalue
    union 
    select 2 as findorder, '{T2}' as find, 'Test 2a Test 2b Test 2c' as newvalue
    union 
    select 3 as findorder, '{T3}' as find, 'Test 3a Test 3b Test 3c' as newvalue
    union 
    select 4 as findorder, '{T4}' as find, 'Test 4a Test 4b Test 4c' as newvalue
    order by find
) 
, t1 AS 
(
    select 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. {T3} Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. {T1} Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. {T2} Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. {T4} Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'::text as textvalue
)

SELECT * 
FROM fandr
ORDER BY findorder DESC LIMIT 1


+---+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+---+
| 1 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Test 3a Test 3b Test 3c Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Test 1a Test 1b Test 1c Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Test 2a Test 2b Test 2c Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Test 4a Test 4b Test 4c Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | {T4} | 4 |
+---+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------+---+

rextester example

【讨论】:

  • 完美的解释和示例,适合我的需要。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
  • 2017-01-10
  • 2010-11-16
相关资源
最近更新 更多