【问题标题】:Teradata macro with volatile table and CTE to insert data into a table具有易失性表和 CTE 的 Teradata 宏,用于将数据插入表中
【发布时间】:2020-01-16 20:44:40
【问题描述】:

我需要先创建一个 teradata 宏来将信息提取到 volatile 表中,然后执行 CTE 从该 volatile 表中提取数据并插入到 teradata 表中,尝试了不同的方法都失败了,感谢帮助!

CREATE MACRO database.macro_insertion_tablename AS (

  CREATE VOLATILE TABLE vt AS
  (
     SELECT
       id, bu,
       CONCAT(TO_CHAR(comment_date, 'yyyy-mm-dd HH24:MI:SS'), ' ', action) AS full_action,
       ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS row_num, 
       COUNT(*) OVER (PARTITION BY id) as cnt
     FROM database.table1
  ) WITH DATA UNIQUE PRIMARY INDEX(id, row_num) ON COMMIT PRESERVE ROWS; 

  WITH RECURSIVE cte (id, bu, act, rn) AS
  (
     SELECT 
       id, bu
       ,CAST(full_action AS VARCHAR(5000)) AS full_action
       ,row_num
     FROM vt
     WHERE row_num = cnt

     UNION ALL

     SELECT
       vt.id, vt.bu 
       ,cte.act || ' / ' || vt.full_action
       ,vt.row_num
     FROM vt
     JOIN cte On vt.id = cte.id AND vt.row_num = cte.rn - 1
  )  

  INSERT INTO database.table (id, bu, full_action)
  SELECT id, bu, act
  FROM cte
  WHERE rn = 1;

  DROP TABLE vt; 
); 

【问题讨论】:

  • 失败是什么意思?这是一个错误还是您没有看到您所期望的?您期待什么结果,目前正在获得什么结果?
  • 请记住,像您定义的可变表仅对创建它的会话可用。
  • 除了指定结果集的分布 (id, row_num) 之外,您需要使用 volatile 表还有什么特别的原因吗?您不能将 volatile 表的结果集作为辅助 CTE 合并到您的 INSERT INTO database.table ... 语句中吗?

标签: teradata


【解决方案1】:

DDL 必须是 Teradata 宏中的 only 语句。

作为解决方法,您可以切换到定义一次的 全局临时表,然后您只需将其插入/选择而不是 CREATE VOLATILE TABLE。

但在您的情况下,不需要临时表和低效的递归处理来获得“组连接”:

SELECT id, max(bu) -- maybe min(bu)?
   XmlAgg(Concat(To_Char(comment_date, 'yyyy-mm-dd HH24:MI:SS'), ' ', action)
          ORDER BY comment_date)  (VARCHAR(5000)) AS full_action
FROM database.table1
GROUP BY 1

会给你类似的结果。

【讨论】:

    【解决方案2】:

    要跟进我的 cmets,您应该能够在同一语句中定义多个 CTE。让RECURSIVE CTE 工作可能很棘手,但听起来这是可能的。也许是这样的:

    CREATE MACRO database.macro_insertion_tablename AS (
    
      WITH vt (id, bu, full_action, row_num, cnt) AS
      (
         SELECT
           id, bu,
           CONCAT(TO_CHAR(comment_date, 'yyyy-mm-dd HH24:MI:SS'), ' ', action) AS full_action,
           ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS row_num, 
           COUNT(*) OVER (PARTITION BY id) as cnt
         FROM database.table1
      ),
      RECURSIVE cte (id, bu, act, rn) AS
      (
         SELECT 
           id, bu
           ,CAST(full_action AS VARCHAR(5000)) AS full_action
           ,row_num
         FROM vt
         WHERE row_num = cnt
    
         UNION ALL
    
         SELECT
           vt.id, vt.bu 
           ,cte.act || ' / ' || vt.full_action
           ,vt.row_num
         FROM vt
         JOIN cte On vt.id = cte.id AND vt.row_num = cte.rn - 1
      )  
    
      INSERT INTO database.table (id, bu, full_action)
      SELECT id, bu, act
      FROM cte
      WHERE rn = 1;
    );
    

    我没有要测试的Teradata 系统,所以不是100% 可以按原样工作,但请试一试。您可能需要将RECURSIVE 更改为WITH RECURSIVE 以及CTE 查询的顺序(即将RECURSIVE 放在第一位)。看看这两个链接:

    Teradata Forum - Multiple With Clause
    teradata Forum - Common Table Expressions

    【讨论】:

    • 谢谢,但不起作用,看起来宏不能插入。我会尝试SP看看它是否有效。
    • 在宏之外单独运行查询会发生什么?尝试分解各个 SELECT 查询,看看它们是否都返回了您期望的行。
    • 试过不工作,只是select 很好,但insert into... select ... 不工作。谢谢。
    • “不工作”是什么意思?是否有错误或没有行被INSERTed 到您的表中?请提供尽可能详细的信息。
    • 我解决了,插入 teradata 递归表的正确语法是insert into table with vt as (sel .... ), recursive rt as ( sel....) select ... from rt,谢谢@ravioli
    猜你喜欢
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多