使用SQL Oracle将另一张表的数据替换一些变量。

huangapple go评论62阅读模式
英文:

Replace some variables by data of another table in sql oracle

问题

我有一个包含两列的表格

类型 文本
A 这是一些文本,包括%1和%2
B 这是另一个步骤,包括%1

在一个翻译表中,我有变量%X的含义,如下所示

类型 变量 描述
A %1 #人员1#
A %2 #人员2#
B %1 #经理#

我想要在我的第一个表中用描述替换所有变量,所以结果应该如下所示:

类型 文本
A 这是一些文本,包括#人员1#和#人员2#
B 这是另一个步骤,包括#经理#

我尝试过使用替换,但没有弄清楚如何让它起作用。

英文:

I have a table with two columns

type TXT
A this is some text for %1 and %2
B this is another step for %1

in a translation table I have the signification of the variables %X that looks like

Type variable descr
A %1 #person1#
A %2 #person2#
B %1 #manager#

I want to replace in my first table all the variables by the description, so the result has to looks like this:

type TXT
A this is some text for #person1# and #person2#
B this is another step for #manager#

I tried with a replace, but I didn't figured out how to make it work

答案1

得分: 1

无法提供代码翻译。

英文:

To replace all variables you could use a recursive algorithm:

with data(typ, txt) as (
    select 'A', 'this is some text for %1 and %2' from dual union all
    select 'B',	'this is another step for %1' from dual 
),
translations(typ, var, description) as (
   select 'A', '%1', '#person1#' from dual union all
   select 'A', '%2', '#person2#' from dual union all
   select 'B', '%1', '#manager#' from dual -- union all
),
rtranslations(typ, var, description,rn) as (
    select t.*, row_number() over(partition by typ order by var) as rn
        from translations t
),
replacecte(typ, txt, replaced_txt, rn) as (
    select d.typ, d.txt, replace(d.txt, t.var, t.description), t.rn
    from data d
    join rtranslations t on t.typ = d.typ
    where t.rn = 1

    union all

    select r.typ, r.txt, replace(r.replaced_txt, t.var, t.description), t.rn
    from replacecte r
    join rtranslations t on t.typ = r.typ and t.rn = r.rn + 1
)
select r.typ, r.txt, replaced_txt from replacecte r
where rn = length(txt) - length(replace(txt,'%',''))
;

答案2

得分: 1

以下是翻译好的代码部分:

你可以不使用递归来实现这种方式。`data`  `descr` 当然只是你表格的模拟,你不需要任何 `WITH` 子句。这种方法使用以下步骤:(1) 将句子分解成单词,(2) 使用这些单词与你的描述表进行外连接,用描述值替换任何匹配项,(3) 使用 `LISTAGG` 将单词重新组合成句子。

    WITH data AS(SELECT 'A' type, 'this is some text for %1 and %2' txt FROM dual
                  UNION ALL
                 SELECT 'B' type, 'this is another step for %1' txt FROM dual
                 ),
         descr AS (SELECT 'A' type, '%1' variable,'#person1#' description FROM dual
                   UNION ALL
                   SELECT 'A' type, '%2' variable,'#person2#' description FROM dual
                   UNION ALL
                   SELECT 'B' type, '%1' variable,'#manager#' description FROM dual)
    SELECT type,
           LISTAGG(new_word,' ') WITHIN GROUP (ORDER BY seq) txt
      FROM (SELECT x.type,
                   NVL(descr.description,x.word) new_word,
                   seq
              FROM (SELECT type,SUBSTR(' '||txt,INSTR(' '||txt,' ',1,seq)+1,INSTR(' '||txt||' ',' ',1,seq+1) - (INSTR(' '||txt,' ',1,seq)+1)) word,seq
                      FROM data,
                           (SELECT ROWNUM seq FROM dual CONNECT BY LEVEL <= 50) x) x,
                   descr
             WHERE x.type = descr.type(+)
               AND x.word = descr.variable(+))
     GROUP BY type

希望这能帮助你!

英文:

You can also do it this way without recursion. data and descr are of course just mock ups for your tables, you would not need any WITH clauses. This method uses the steps (1) break up the sentences into words, (2) outer join using those words to your description table, replacing any matches with the description values, (3) reassemble the words back into sentences using LISTAGG.

WITH data AS(SELECT &#39;A&#39; type, &#39;this is some text for %1 and %2&#39; txt FROM dual
              UNION ALL
             SELECT &#39;B&#39; type, &#39;this is another step for %1&#39; txt FROM dual
             ),
     descr AS (SELECT &#39;A&#39; type, &#39;%1&#39; variable,&#39;#person1#&#39; description FROM dual
               UNION ALL
               SELECT &#39;A&#39; type, &#39;%2&#39; variable,&#39;#person2#&#39; description FROM dual
               UNION ALL
               SELECT &#39;B&#39; type, &#39;%1&#39; variable,&#39;#manager#&#39; description FROM dual)
SELECT type,
       LISTAGG(new_word,&#39; &#39;) WITHIN GROUP (ORDER BY seq) txt
  FROM (SELECT x.type,
               NVL(descr.description,x.word) new_word,
               seq
          FROM (SELECT type,SUBSTR(&#39; &#39;||txt,INSTR(&#39; &#39;||txt,&#39; &#39;,1,seq)+1,INSTR(&#39; &#39;||txt||&#39; &#39;,&#39; &#39;,1,seq+1) - (INSTR(&#39; &#39;||txt,&#39; &#39;,1,seq)+1)) word,seq
                  FROM data,
                       (SELECT ROWNUM seq FROM dual CONNECT BY LEVEL &lt;= 50) x) x,
               descr
         WHERE x.type = descr.type(+)
           AND x.word = descr.variable(+))
 GROUP BY type

答案3

得分: 0

你可以使用 PIVOT 将行中的变量值转换为列(将所有变量在同一行中与文本一起),然后根据变量值的数量执行多次替换:

SELECT      t.A_TYPE, 
            CASE  WHEN d.V3 Is Not Null  THEN REPLACE(REPLACE(REPLACE(t.TXT, '%1', d.V1), '%2', d.V2), '%3', d.V3)
                  WHEN d.V2 Is Not Null  THEN REPLACE(REPLACE(t.TXT, '%1', d.V1), '%2', d.V2)
                  WHEN d.V1 Is Not Null  THEN REPLACE(t.TXT, '%1', d.V1)
            ELSE  t.TXT
            END "TXT"
FROM        tbl t
INNER JOIN  ( SELECT  *
              FROM    ( Select A_TYPE, VAR, DESCRIPTION FROM descr  )
                      PIVOT ( MAX(DESCRIPTION) For VAR IN('%1' "V1", '%2' "V2", '%3' "V3") )
            ) d ON(d.A_TYPE = t.A_TYPE)

带有示例数据的部分如下:

WITH 
    tbl (A_TYPE, TXT) AS
        (
            Select 'A', 'this is some text for %1 and %2'  From Dual Union All
            Select 'B', 'this is another step for %1'      From dual
        ),
     descr (A_TYPE, VAR, DESCRIPTION) AS 
        (
            Select 'A', '%1', '#person1#'  From Dual UNION ALL
            Select 'A', '%2', '#person2#'  From Dual UNION ALL
            Select 'B', '%1', '#manager#'  From Dual
        )

结果应如下所示:

A_TYPE TXT                                            
------ -----------------------------------------------
A      this is some text for #person1# and #person2#  
B      this is another step for #manager#            
英文:

You could use PIVOT to get the var values from rows into columns (geting all vars in the same row with text) and then do multiple replaces depending on number of var values:

SELECT      t.A_TYPE, 
            CASE  WHEN d.V3 Is Not Null  THEN REPLACE(REPLACE(REPLACE(t.TXT, &#39;%1&#39;, d.V1), &#39;%2&#39;, d.V2), &#39;%3&#39;, d.V3)
                  WHEN d.V2 Is Not Null  THEN REPLACE(REPLACE(t.TXT, &#39;%1&#39;, d.V1), &#39;%2&#39;, d.V2)
                  WHEN d.V1 Is Not Null  THEN REPLACE(t.TXT, &#39;%1&#39;, d.V1)
            ELSE  t.TXT
            END &quot;TXT&quot;
FROM        tbl t
INNER JOIN  ( SELECT  *
              FROM    ( Select A_TYPE, VAR, DESCRIPTION FROM descr  )
                      PIVOT ( MAX(DESCRIPTION) For VAR IN(&#39;%1&#39; &quot;V1&quot;, &#39;%2&#39; &quot;V2&quot;, &#39;%&#39; &quot;V3&quot;) )
            ) d ON(d.A_TYPE = t.A_TYPE)

With sample data as:

WITH 
    tbl (A_TYPE, TXT) AS
        (
            Select &#39;A&#39;, &#39;this is some text for %1 and %2&#39;  From Dual Union All
            Select &#39;B&#39;, &#39;this is another step for %1&#39;      From dual
        ),
     descr (A_TYPE, VAR, DESCRIPTION) AS 
        (
            Select &#39;A&#39;, &#39;%1&#39;, &#39;#person1#&#39;  From Dual UNION ALL
            Select &#39;A&#39;, &#39;%2&#39;, &#39;#person2#&#39;  From Dual UNION ALL
            Select &#39;B&#39;, &#39;%1&#39;, &#39;#manager#&#39;  From Dual
        )

... the result should be

A_TYPE TXT                                            
------ -----------------------------------------------
A      this is some text for #person1# and #person2#  
B      this is another step for #manager#            

huangapple
  • 本文由 发表于 2023年2月14日 21:50:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75448797.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定