8

今天是个好日子。我想问一个关于我的 SQL 语句的问题。我正在使用 SQL Server 2008 并有一个名为 Workflow Transaction 的表。在这张表中,我有 12 条记录。下图是表格的内容。

在此处输入图像描述

我有这个 SQL 语句:

UPDATE Workflow_Txn 
SET Status = 1
WHERE [RequestId] IN
(
    SELECT [RequestId]
    FROM Workflow_Txn 
    WHERE [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)      
    AND RequestId = 3
)

我的目标是更新 OrderNumber 小于最大值的请求 ID,这将是 WHERE 子句中 SELECT 语句的输出。现在我希望要更新的记录应该只是上述记录(在代码中,它是 RequestId #3)。

实际发生的情况不是只更新了四条记录,而是变成了五 (5) 条!我现有的 SQL 语句有问题吗?

4

3 回答 3

6

您的问题是您正在使用 RequestId = 3 更新所有记录。考虑到您的子查询结果是3这样您最终会更新所有相关记录。

您的查询相当于做

UPDATE Workflow_Txn 
SET Status = 1
WHERE RequestId = 3

不确定您是否有任何理由让您的查询比它需要的更复杂。在我看来,更简单的东西可以解决问题

UPDATE Workflow_Txn 
SET    Status = 1
WHERE  [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)      
       AND RequestId = 3
于 2013-07-23T13:20:23.050 回答
6

您的查询的问题是子查询非常详细地查找订单号小于最大值的记录。然后它选择具有相同请求的所有内容——包括最大订单号。

我更喜欢使用 CTE 解决此问题,如下所示:

with toupdate as (
      select t.*,
             MAX(OrderNumber) as MaxON
      from Workflow_txn
      where RequestId = 3
     )
UPDATE toupdate
    SET Status = 1
    where OrderNumber < MaxON;

我喜欢这种结构,因为我可以单独运行 CTE 来查看哪些记录可能会被更新。

要修复您的查询,您可以将请求更改为 usingOrderNumber并重复RequestId = 3

UPDATE Workflow_Txn 
SET Status = 1
WHERE [RequestId] = 3 and
      OrderNumber in
(
    SELECT [OrderNumber]
    FROM Workflow_Txn 
    WHERE [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)      
    AND RequestId = 3
)
于 2013-07-23T13:20:54.783 回答
4

您的子查询刚刚说返回 RequestID 为 3,因此您使用该 ID 更新了所有请求;走过去。我认为你正在寻找的是这样的:

UPDATE Workflow_Txn 
SET Status = 1
WHERE [RequestId] = 3
AND  [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3) 
于 2013-07-23T13:22:39.467 回答