一个cte的多个语句?

时间:2018-04-17 08:08:32

标签: sql sql-server

以下内容的正确语法是什么? (我在一个查询中需要theese)

 --- 1. task
 update A set .... where ....
 insert into A (...) values (...);

 --- 2 .task
 With cte as (select A.column...)
 update A set ... if condition1(includes cte table)
 update A set ... if condition2(includes cte table)
 update A set ... if condition3(includes cte table)

用语言说:

  1. 我更新表格A或插入其中
  2. 之后我在cte表中引用这个更新的TableA,它包含一个ROW_NUMBER函数,
  3. 然后我想再次更新TableA依赖于特定行中CTE的rownumber,例如:如果CTE中的rownumber值为1,那么执行此操作,如果它是该特定行的max(rownumber)则执行该....
  4. 我读到cte-s只能用于单个语句。我试图复制每个更新语句的cte,用分号分隔,但是没有用。我读到了MERGE,但我不确定这是否是正确的方法。它是OUTPUT子句,如果是,如何使用它?或者是其他东西?你能帮帮我吗?

2 个答案:

答案 0 :(得分:1)

您不需要多个更新声明。你可以用一个。

; WITH CTE as ( select . . . )
UPDATE A
SET    col1 = case when .... then new_1 else col1 end,
       col2 = case when .... then new_2 else col2 end
FROM   CTE as A

答案 1 :(得分:0)

正确,CTE仅存在于其存在的语句中。因此,如下所示的语句将失败:

WITH CTE AS(
    SELECT *,ROW_NUMBER() OVER (PARTITION BY Date ORDER BY ID) AS RN
    FROM YourTable)
SELECT *
FROM CTE
WHERE RN = 1;

SELECT *
FROM CTE
WHERE RN = 2;

那是因为在第二次陈述期间CTE不再存在。

对于UPDATE(或任何声明),您每次都需要重新声明您的CTE。因此,使用上面的示例,您将不得不这样做:

WITH CTE AS(
    SELECT *,ROW_NUMBER() OVER (PARTITION BY Date ORDER BY ID) AS RN
    FROM YourTable)
SELECT *
FROM CTE
WHERE RN = 1;

WITH CTE AS(
    SELECT *,ROW_NUMBER() OVER (PARTITION BY Date ORDER BY ID) AS RN
    FROM YourTable)    
SELECT *
FROM CTE
WHERE RN = 2;

如果CTE中的表达式非常复杂,并且您经常使用它们,则可以考虑使用VIEW