使用CTE更新

时间:2014-05-13 12:18:08

标签: sql sql-server-2008 tsql reportbuilder3.0

我有以下查询:

;WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY col1,col2) rno FROM @table
)
DELETE c1 FROM cte c1
LEFT JOIN cte c2 ON (c1.rno = c2.rno+1 OR c1.rno = c2.rno-1) AND c1.rid = c2.rid
WHERE c2.id IS NULL

我没有删除我想要更新列,而是尝试了以下内容:

;WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY col1,col2) rno FROM @table
)
UPDATE cte
SET col3='Test'
LEFT JOIN cte c2 ON (c1.rno = c2.rno+1 OR c1.rno = c2.rno-1) AND c1.rid = c2.rid
WHERE c2.id IS NULL

但收到以下错误:

Incorrect syntax near the keyword 'LEFT'

2 个答案:

答案 0 :(得分:3)

您缺少FROM子句:

;WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY col1,col2) rno FROM @table
)
UPDATE c1
SET col3='Test'
FROM cte c1 -- MISSING HERE
LEFT JOIN cte c2 ON (c1.rno = c2.rno+1 OR c1.rno = c2.rno-1) AND c1.rid = c2.rid
WHERE c2.id IS NULL;

您还可以使用NOT EXISTSmay perform better in SQL Server而不是LEFT JOIN/IS NULL

;WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY col1,col2) rno FROM @table
)
UPDATE cte
SET col3='Test'
WHERE NOT EXISTS (SELECT 1
                    FROM cte c2
                    WHERE (cte.rno = c2.rno+1 OR cte.rno = c2.rno-1) 
                    AND cte.rid = c2.rid);

答案 1 :(得分:1)

LEFT JOIN符合FROM条款。你是说这个吗?

WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY col1,col2) rno FROM @table
)
UPDATE c1
SET col3='Test'
FROM c1 LEFT JOIN
     cte c2
     ON (c1.rno = c2.rno+1 OR c1.rno = c2.rno-1) AND c1.rid = c2.rid
WHERE c2.id IS NULL;

注意我将更新从cte切换到c1,因为您正在寻找没有匹配项。该查询看起来很奇怪。可能有另一种方法可以实现您想要的效果。在一个问题中,样本数据和期望的结果非常有用。