在INSERT语句中使用WITH子句

48

我想知道是否有可能。我有一个现有的查询,使用WITH子句将一些汇总数据应用于SELECT查询,如下所示:(大大简化)

;WITH alias (y,z)
AS
(
    SELECT y,z FROM tableb
)
SELECT y, z FROM alias

我现在想要将这个查询的结果插入到另一个表中。

我尝试了以下操作:

INSERT INTO tablea(a,b)
;WITH alias (y,z)
AS
(
    SELECT y,z FROM tableb
)
SELECT y, z FROM alias

但我得到了以下错误:

分号附近语法不正确。

所以我尝试没有分号,但是得到了以下错误:

关键词“WITH”附近的语法不正确。

关键词“with”附近的语法不正确。如果此语句是公共表达式或 xmlnamespaces 子句,则必须使用分号终止前一语句。

我正在尝试的操作是否可以使用不同的语法实现?


分号应该放在语句的末尾。把它放在前面是一个不好的习惯,你应该习惯于用分号正确地终止每个语句。 - user330315
你有查看文档中关于INSERT语句的内容吗?它展示了CTE在INSERT之前的语法,并提供了使用CTE的例子。 - Pondlife
5个回答

88
你需要在 CTE 后面放置 INSERT INTO。因此,代码将如下所示:
;WITH alias (y,z)
AS
(
    SELECT y,z FROM tableb
)
INSERT INTO tablea(a,b)
SELECT y, z 
FROM alias

请参见带演示的SQL Fiddle


1

如果不使用CTE的另一种方法是将其包装在子查询中。

INSERT INTO tablea(a,b)
SELECT y, z 
FROM 
(
    SELECT y,z FROM tableb
) alias

@KSTech 很好的问题。我认为原帖只是简化了问题。 - John Woo

0
在我的情况下,建议的答案不适用,我认为这可能是SQL Server版本的问题,而我的版本是SQL Server 2016。或者您可以通过以下代码片段使用临时表:
;WITH alias (y,z)
AS (SELECT y,z FROM tableb)
SELECT Y,Z
INTO #TEMP_TABLE
FROM alias

Z


0
db2 上是可能的。
免责声明:
我将使用一个完全不同的示例来回答问题。
SQL 脚本
/*
 * DBeaver Version 23.2.0.202309041200
 * `db2:11.5.8` See. https://hub.docker.com/r/ibmcom/db2/tags.
 * 
 * DDL use for the example.
 * 
 * The next three tables contain portion for the "Travel" entity.
 * 
 * CREATE TABLE "TEST-SCHEMA"."TRAVEL"  (
 * "TRAVELID" INTEGER NOT NULL, "PASSANGER_QUANTITY" INTEGER ) IN
   "USERSPACE1" ORGANIZE BY ROW;
 *
 * CREATE TABLE "TEST-SCHEMA"."TRAVEL_RATE" (
 * "TRAVELID" INTEGER NOT NULL, "RATE" DOUBLE ) IN "USERSPACE1" ORGANIZE
   BY ROW;
 *
 * CREATE TABLE "TEST-SCHEMA"."TRAVEL_TIME_TO_ARRIVE"  (
 * "TRAVELID" INTEGER NOT NULL, "TIME_TO_ARRIVE" INTEGER ) IN
   "USERSPACE1" ORGANIZE BY ROW;
 *
 * 
 * This table show a full "Travel" entity collecting data from the tables listed above.
 * 
 * CREATE TABLE "TEST-SCHEMA"."TRAVEL_RESULT"  (
          "TRAVELID" INTEGER , 
          "PASSANGER_QUANTITY" INTEGER , 
          "RATE" DOUBLE , 
          "TIME_TO_ARRIVE" INTEGER )   
         IN "USERSPACE1"  
         ORGANIZE BY ROW; 
 * */

-- This sintax use `WITH` and `INSERT` statements.

INSERT INTO "TEST-SCHEMA".TRAVEL_RESULT (
  TRAVELID, PASSANGER_QUANTITY, RATE, TIME_TO_ARRIVE
)
WITH 
collect_travel AS (
    SELECT 
        TRAVELID, PASSANGER_QUANTITY
    FROM "TEST-SCHEMA".TRAVEL
),
collect_rate AS (
    SELECT 
        TRAVELID, RATE
    FROM "TEST-SCHEMA".TRAVEL_RATE
),
collect_time_to_arrive AS (
    SELECT 
        TRAVELID, TIME_TO_ARRIVE
    FROM "TEST-SCHEMA".TRAVEL_TIME_TO_ARRIVE 
)
SELECT 
    collect_travel.TRAVELID,
    collect_travel.PASSANGER_QUANTITY,
    collect_rate.RATE,
    collect_time_to_arrive.TIME_TO_ARRIVE
  
FROM 
    collect_travel
    LEFT JOIN collect_rate ON collect_travel.TRAVELID = collect_rate.TRAVELID
    LEFT JOIN collect_time_to_arrive ON collect_travel.TRAVELID = collect_time_to_arrive.TRAVELID
;

结果集

Result set

希望对你有所帮助!

0
分号用于终止语句。因此,当您使用;WITH时,会终止前面的语句。然而,这不是您在此处收到错误的原因。问题在于您的INSERT INTO语句,它正在寻找VALUES或SELECT语法。

INSERT INTO语句可以有两种用法-通过显式提供VALUES或通过使用SELECT语句提供结果集。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接