SQL插入使用WITH语句会引发意外的“插入”错误

时间:2019-06-26 14:23:31

标签: sql snowflake-datawarehouse

作为我的SQL查询的一部分,我首先根据某些条件创建了一个名为“ new”的表,然后根据该表insert into从另一表new的某些列中old一定条件下。这是我要做的事情的简化版本:

   item    | subitem    |   stage    |   id     | 
    -----------------------------------------------
    i1      | s1         |  picked    |    1     |
    i1      | s2         |  shipped   |    1     |
    i2      | s4         |  picked    |    2     |
    i3      | s10        | shipped    |    2     |
    i3      | s11        | eligible   |    0     |
    i4      | s2         |not eligible|    0     |
    i1      | s1         |  picked    |    3     |
    i1      | s2         |  picked    |    3     |

我希望输出如下:

    item1|subitem1|item2|subitem2|pair_volume|item1pick|item1ship|item2pick|item2ship|
-------------------------------------------------------------------------------------
    i1   |   s1   |  i1 | s2     | 2         |  2      | 0       | 2       | 1       |
    i1   | s1     | i2  | s4     | 1         |1        | 0       | 1       | 1       |  
    ....
    .....
    ....

本质上,我想在这里做的是以下事情:

我想首先将item, subitem与自身进行交叉联接,因此我拥有item1subitem1item2,{{1}的所有可能组合}。

这是定义阶段的方式。如果一个阶段是合格的,那么它就是合格的,而如果选择了一个阶段,则意味着该项目既是合格的又是被选择的。如果运送了一个阶段,则意味着该物品是合格的,已拣配并已运送。仅提及最后一个阶段。

现在,对于每对subitem2,我要计算该对发生的item1, subitem1 - item2, subitem2会话的数量,并在id中具有阶段,并在(eligible, shipped, picked)中填充值。例如,pair_volume对出现两次(在(i1,s1)-(i1,s2) 1中发生一次,在id 3中发生一次),并且在这两个id会话中,该对中的两个项目均为{{ 1}}(从ideligible隐含)阶段。在这对符合条件的货币对发生的2次中,item1提货了多少次,item2提货了多少,item1发货了,item2发货了几次?这就是我要解决的问题。

我可以做得很好,直到交叉加入为止。但是我不知道如何将值插入到交叉联接表中。真正的问题比我在这里提到的要复杂得多。任何帮助深表感谢! 这是我到目前为止的查询:

picked

从本质上讲,这是我要在此处执行的操作,并且shipped语句不断抛出错误。到with new as ( select combination.item1, combination.subitem1, combination.item2, combination.subitem2, ( select tmp.item1, tmp.subitem1, tmp.item2, tmp.subitem2, case when ((tmp.item1 = tmp.item2) and (tmp.subitem1 = tmp.subitem2)) then 'TRUE' else 'FALSE' end as indicator from ( select distinct item as item1, subitem as subitem2 from old cross join select distinct item as item2, subitem as subitem2 from old ) tmp ) combination where combination.indicator = 'FALSE' ) insert into new (pair_volume) select count(id) as pair_volume from old where ((new.item1 = old.item) and (new.subitem1 = old.subitem) and stage in ('picked', 'eligible', 'shipped')) and ((new.item2 = old.item) and (new.subitem2 = old.subitem) and stage in ('picked', 'eligible', 'shipped') 为止的那部分效果很好。但是我在将值插入表以及为所需的输出表做出正确条件时遇到了麻烦。非常感谢任何帮助!

但是,这为我抛出了一个错误,如下所示:

  

SQL编译错误:位置0处的语法错误第4行出现意外的“插入”。

我尝试在insert into语句前加入半冒号,这就是我得到的:

  

SQL编译错误:位置1处的语法错误第3行出现意外的';'。

我尝试在cross join语句前加入逗号insert into,这是我得到的:

  

SQL编译错误:位置0处的语法错误第4行出现意外的“插入”。位置0的语法错误第5行出现意外的“选择”。

我在这里做错了什么?根据许多其他帖子,我发现这就是我们在CTE中使用,的方式。

2 个答案:

答案 0 :(得分:0)

如评论中所述,您非常接近,但是CTE不会创建表,这就是为什么它不起作用的原因。

此位很好:

with new as
(
select combination.item1, combination.subitem1, combination.item2, 
combination.subitem2,
    (
    select tmp.item1, tmp.subitem1, tmp.item2, tmp.subitem2,
    case when ((tmp.item1 = tmp.item2) and 
    (tmp.subitem1 = tmp.subitem2)) then 'TRUE' else 
    'FALSE' end as indicator from
        (
        select distinct item as item1, subitem as subitem2
        from old
        cross join
        select distinct item as item2, subitem as subitem2 
        from old
        ) tmp
    ) combination
where combination.indicator = 'FALSE'
)

下一行:

insert into new (pair_volume)

您不能插入新的。没有称为“新”的表。即使您可以插入CTE,也没有名为pair_volume的列。

您需要创建一个单独的表来包含要创建的数据输出。

您有固定数量的子项目吗?如果不是,它将变得更加复杂,您将需要使用动态SQL来构建查询以获取所需的结果,或者如果RDBMS支持它,则可以使用SELECT INTO从结果集中动态创建表。

答案 1 :(得分:0)

如果您没有义务使用CTE(基本上,当您想创建新表时,使用CTE并没有多大意义),可以尝试一下,例如:

INSERT INTO new (tmp1, tmp2)
SELECT tmp1,tmp2
FROM old

编辑:使用SQL Server