与 CTE 一起与 CREATE/INSERT 一起使用

Posted

技术标签:

【中文标题】与 CTE 一起与 CREATE/INSERT 一起使用【英文标题】:Using With CTE Together With CREATE/INSERT Sequentially 【发布时间】:2019-12-13 16:08:33 【问题描述】:

我正在尝试转换一些大型数据集,我发现最优化的方法是在 Oracle 中编写 CTE。在性能方面,我发现它与本文 (https://www.mssqltips.com/sqlservertip/5118/sql-server-cte-vs-temp-table-vs-table-variable-performance-test/) 的结果非常接近。

但是,问题是还需要通过此过程以顺序方式创建表。但是,我发现虽然我能够使用 CTE 创建表;我不能在 CTE 之后使用 CREATE TABLE 语句,只能在之前使用。

我发现以下方法可行。但出于某种原因,我必须一次运行一个 DROP TABLE 和 CREATE TABLE 语句。有什么方法可以修改以下代码,以便我只需运行一次脚本就可以更新 tmp 和 tmp2 表?

代码示例:

DROP TABLE tmp PURGE; 
DROP TABLE tmp2 PURGE; 

CREATE TABLE tmp ( tmp_id NUMBER(10));  
CREATE TABLE tmp2 ( tmp_id NUMBER(10));

/* Part I - Insert the first table using WITH CTE */
INSERT INTO tmp( tmp_id )
WITH cte AS (
  SELECT 1 AS tmp_id FROM dual union all
  SELECT 2 AS tmp_id FROM dual
)
SELECT tmp_id
FROM cte;

/* Part II- Use tmp table created above in another CTE*/
INSERT INTO tmp2( tmp_id )
WITH cte AS (
  SELECT tmp_id from tmp
)
SELECT tmp_id
FROM cte;

--/*Just for testing*/ select * from tmp
--/*Just for testing*/ select * from tmp2

【问题讨论】:

为什么要删除并重新创建表?如果您想删除数据,只需在每个表上使用 truncate - 是的,一次 1 个。顺便说一句,您关于使用 CTE 创建表的 cmets 不正确;表已经创建,您的 CTE 正在填充它们。 您好,Belayer,感谢您对评论的建议。我可以更改为 TRUNCATE 而不是 CREATE。但是,有没有办法一次修改所有表格?这就是问题的症结所在。谢谢日元 你可以试试multi-table insert? 是的。截断从表中删除所有数据而不创建回滚可能性。它实际上重置了表的高水位线,从而有效地擦除了所有数据。但是表结构,包括约束、触发器等仍然有效。删除并重新创建会删除数据以及结构。 我完全不明白:我发现虽然我可以使用 CTE 创建表;我不能在 CTE 之后使用 CREATE TABLE 语句,只能在之前使用。 什么不完全有效?然后您以询问更新结束,但您的示例不包含任何更新。 【参考方案1】:

您不能在 CTE 之后使用 CREATE TABLE 语句的原因是因为 CTE 是 SELECT 指令的一部分。 'SELECT * from table DELETE TABLE2' 没有意义。它必须是 2 个单独的指令。

为什么你必须在你的表中 DROP 然后 CREATE 然后 INSERT ?您可以将数据直接插入到新表中,这只是一条指令。看 : SQL Server SELECT into existing table

如果你想重新运行你的脚本,你可以在执行插入之前截断你的表,正如 Belayer 在评论中所说的那样

【讨论】:

以上是关于与 CTE 一起与 CREATE/INSERT 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

将 IF EXISTS 与 CTE 一起使用

Postgres - 使用 CTE 的 id 列的唯一值,与 GROUP BY 一起加入

你如何与多个 CTE 联合?

如何正确应用递归 CTE?

sql MS SQL内部连接与子查询与CTE

从有序 CTE、TOP 与 Range 中检索 X 行