teradata中是否有办法替换另一张表中的一行中的多字符串?

时间:2019-01-09 16:45:23

标签: teradata

我有两个表CustomerRoad_AB

客户表数据:

id Add
1  India NW
2  Poland NW HV
3  ASIA HV

Road_AB数据:

text abb
NW   NEW
HV   Heaven

我的要求是在Customer的{​​{1}}表上执行更新。 一行中可能有多个字符串需要更新。

更新后的预期结果:

Road_AB表数据:

Customer

1 个答案:

答案 0 :(得分:1)

这里最棘手的部分是,您将必须对Road_ab表的列进行任意细分,这无疑会导致各种头部刮伤。值得庆幸的是,Teradata具有出色的strtok_split_to_table函数,可让您将记录中的列拆分为分隔符上的多个记录。因此,我们可以将India NW分成两个记录IndiaNW,并以空格分隔。然后,我们可以联接并使用XMLAGG()将这些拆分后的字符串重新联接在一起。这些功能使我们能够在整个过程中保留顺序并记录密钥。

以下是使用示例数据的有效示例:

CREATE MULTISET VOLATILE TABLE Customer(
   id  INTEGER  
  ,Addf VARCHAR(30) NOT NULL
) ON COMMIT PRESERVE ROWS;
INSERT INTO Customer(id,Addf) VALUES (1,'India NW');
INSERT INTO Customer(id,Addf) VALUES (2,'Poland NW HV');
INSERT INTO Customer(id,Addf) VALUES (3,'ASIA HV');

CREATE MULTISET VOLATILE TABLE Road_AB(
   textf CHAR(2)  
  ,abb  VARCHAR(30) NOT NULL
) ON COMMIT PRESERVE ROWS;
INSERT INTO Road_AB(textf,abb) VALUES ('NW','NEW');
INSERT INTO Road_AB(textf,abb) VALUES ('HV','Heaven');

SELECT splitCustomer."id",  TRIM(TRAILING ',' FROM (XMLAGG(TRIM(COALESCE(road_ab.abb, splitCustomer.token))|| '' ORDER BY splitCustomer.TokenNum) (VARCHAR(10000), CHARACTER SET UNICODE)))
FROM 
    (
        SELECT * 
        FROM TABLE (STRTOK_SPLIT_TO_TABLE(customer.id, customer.addf, ' ')
         RETURNS (id integer 
         ,tokennum INTEGER
         ,token VARCHAR(30) CHARACTER SET UNICODE)
         ) AS dt
    ) splitCustomer
    LEFT OUTER JOIN road_ab
        ON trim(splitCustomer.token) = trim(road_ab.textf)
GROUP BY 1;

DROP TABLE customer;
DROP TABLE Road_ab;


+----+-------------------+
| id |        add        |
+----+-------------------+
|  3 | ASIA Heaven       |
|  2 | Poland NEW Heaven |
|  1 | India NEW         |
+----+-------------------+

值得注意的是,如果您有大量数据,这将不会很快。您的索引在这里无济于事,因为我们必须生成一个临时结果集,该结果集将比源数据大很多倍,将其连接到您的road_ab表中,然后经历字符串的痛苦聚合。

还值得注意的是,如果Add中的Customer列的大小不合适,则可能会失败。看起来您正在用较大的单词替换较小的单词,并且如果这些单词超出了列的大小,则基于此SELECT的INSERT将会失败。