【问题标题】:CREATE TABLE with CTE statement使用 CTE 语句创建 TABLE
【发布时间】:2016-06-20 22:25:00
【问题描述】:

是否可以使用 CTE 语句从查询创建表? 比如:

CREATE TABLE db1.test1 AS
(
  WITH cte1(v1) as
  ( SEL v1 FROM db1.table1 )

  SEL * FROM cte1

)

这就是 CTE 的样子:

WITH employees(id, name, boss, senior_boss) AS
(
SEL
empls.id,
empls.name,
supervisors.name as boss,
senior_bosses.name as senior_boss

FROM empl_cte AS empls
LEFT JOIN empl_cte AS supervisors ON empls.boss_id = supervisors.id
LEFT JOIN empl_cte AS senior_bosses ON supervisors.boss_id = senior_bosses.id
),

WITH empl_cte(....) AS
(

SEL
id, 
name
boss_id

FROM all_employees
WHERE <some_filters>
)

SEL

*

FROM products
LEFT JOIN employees ON products.sales_rep_id = employees.id

两个

  • 将 CTE 转换为视图

  • employees 转换为左连接中的子查询(empl_cte 作为视图)

导致性能大幅下降(运行时间从几分钟增加到几天)。我无法弄清楚 Teradata 优化器是如何工作的。 EXPLAIN 在新的重构查询上似乎表明 LEFT JOIN 成为一个消耗无数时间的产品连接。

【问题讨论】:

  • Afaik 没有。除了先创建表然后insert into test1 with ... 之外似乎没有其他解决方法
  • 你能把你的 CTE 变成一个视图吗?如果是这样,那么您的 create table 语句将起作用。
  • @Nick 我可以,但在性能方面这是一场灾难
  • 是的,左外连接绝对可以杀死查询。是否可以使用全局临时表而不需要创建表作为选择?
  • 不,我不能使用 GTT,因为我使用的管道不支持。

标签: teradata


【解决方案1】:

这适用于 V16(可能还有更早的版本)。

CREATE TABLE myTable AS (
    SELECT * FROM (
        WITH x AS (
            SELECT ...
            FROM  ...
            WHERE  ...
            ) 
        SELECT  ...
        FROM x ...
        WHERE  ...
        ) D
) WITH DATA PRIMARY INDEX (PK)
;

基本上,您需要将整个查询(包括 CTE)包装在带有别名的 SELECT 中。

【讨论】:

    猜你喜欢
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    相关资源
    最近更新 更多