Question

I have the following query:

;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

Rather than delete I want to update a column, I have tried the following:

;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

but get the following error:

Incorrect syntax near the keyword 'LEFT'
Was it helpful?

Solution

You are missing the FROM clause:

;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;

You could also use NOT EXISTS, which may perform better in SQL Server than 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);

OTHER TIPS

LEFT JOIN goes in a FROM clause. Do you mean this?

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;

Note I switched the update from cte to c1, because you are looking for no matches. That query looks strange. There may be an alternative way to accomplish what you want. Sample data and desired results are very helpful in a question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top