如何使用SQL中的“With”子句更新值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用SQL中的“With”子句更新值相关的知识,希望对你有一定的参考价值。

我想根据'With'子句中的结果更新表的列。当我在update语句中使用tb时,它显示无效的对象名称,因为它已经在'With'子句中。如果有人可以帮我这个。谢谢!

;WITH Split_Segments AS 
(
    SELECT 
        W.ROW_ID
    FROM 
        table1 W
    WHERE
        W.ERRORS IS NULL AND W.UserName = @userId
),
tb AS 
(
    SELECT DISTINCT
        ROW_ID, AP
    FROM 
        Split_Segments 
    WHERE 
        LEN(AP) <> 3  
)
SELECT 
    A.ROW_ID
INTO 
    #tempTable
FROM
    Split_Segments  A
INNER JOIN 
    table4 B ON A.ROW_ID = B.ROW_ID
             AND A.AP = B.AP
LEFT OUTER JOIN 
    tb Z ON A.ROW_ID = Z.ROW_ID
WHERE 
    Z.AP IS NULL;

我想运行以下声明:

UPDATE W SET ERRORS = 'Error' 
FROM table5 W
INNER JOIN tb T ON W.ROW_ID = T.ROW_ID
WHERE AP IS NOT NULL;
答案

好的,如果我按照正确的方式行事,那么这就是您要执行的更新,对吧? UPDATE W SET ERRORS = 'Error' FROM table5 W INNER JOIN tb T ON W.ROW_ID = T.ROW_ID WHERE AP IS NOT NULL;

要做到这一点,你需要tb,这是一个CTE ...所以添加它:

;WITH tb AS ( SELECT DISTINCT ROW_ID, AP FROM Split_Segments WHERE LEN(AP) <> 3
) UPDATE W SET ERRORS = 'Error' FROM table5 W INNER JOIN tb T ON W.ROW_ID = T.ROW_ID WHERE AP IS NOT NULL;

现在tb还需要Split_Segments,这也是一个CTE,因此也需要包含......

;WITH Split_Segments AS ( SELECT W.ROW_ID FROM table1 W WHERE W.ERRORS IS NULL AND W.UserName = @userId ),tb AS ( SELECT DISTINCT ROW_ID, AP FROM Split_Segments WHERE LEN(AP) <> 3
) UPDATE W SET ERRORS = 'Error' FROM table5 W INNER JOIN tb T ON W.ROW_ID = T.ROW_ID WHERE AP IS NOT NULL;

那里......现在它应该工作......更新中没有任何东西需要临时表或除了CTE之外的任何其他东西....

另一答案

你只能在SELECT声明结尾处运行一个UPDATEWITH。由于您已指定需要访问此CTE子句之外的#tempTable,但该表依赖于tb进行构造,我建议将tb移动到临时表:

Remove tb from within the WITH clause:

 --Provisioning tb as temp table outside of CTE
 SELECT DISTINCT 
   ROW_ID, 
   AP
 INTO tb
 FROM table2
 WHERE LEN(AP) <> 3;

--Provisioning temp table outside of CTE
SELECT A.ROW_ID
INTO #tempTable
FROM table3 A
  INNER JOIN table4 B ON A.ROW_ID = B.ROW_ID
    AND A.AP = B.AP
  LEFT OUTER JOIN tb Z ON A.ROW_ID = Z.ROW_ID
WHERE Z.AP IS NULL;

WITH Split_Segments AS (
    SELECT 
      W.ROW_ID
    FROM 
      table1 W
    WHERE
      W.ERRORS IS NULL AND W.UserName = @userId)

UPDATE W SET ERRORS = 'Error' 
FROM table5 W
  INNER JOIN tb T ON W.ROW_ID = T.ROW_ID
WHERE AP is not null;

编辑:根据表意外情况的数量,为什么不直接使用所有涉及的数据集的临时表?:

SELECT W.ROW_ID
INTO #tempSplit_Segments
FROM table1 W
WHERE W.ERRORS IS NULL AND W.UserName = @userId

SELECT DISTINCT ROW_ID, AP
FROM #tempSplit_Segments 
WHERE LEN(AP) <> 3;

SELECT A.ROW_ID
INTO #tempTable
FROM #tempSplit_Segments A
  INNER JOIN table4 B ON A.ROW_ID = B.ROW_ID
    AND A.AP = B.AP
  LEFT OUTER JOIN tb Z ON A.ROW_ID = Z.ROW_ID
WHERE Z.AP IS NULL;

UPDATE W SET ERRORS = 'Error' 
FROM table5 W
  INNER JOIN tb T ON W.ROW_ID = T.ROW_ID
WHERE AP is not null;

以上是关于如何使用SQL中的“With”子句更新值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spark SQL 中的 WITH 子句中缓存子查询结果

我可以在 IN 子句中使用 WITH 子句中的表吗?

在 PHP 中使用 SQL “WITH”子句

如何在标准 SQL 的 WHERE 子句中使用 WITH 子查询作为选项列表

不支持 spark sql 上下文中的 WITH 子句

IN子句效率中的preparedstatement设置值