Good day everyone. I would like to ask a question regarding my SQL statement. I am using SQL Server 2008 and has a table called Workflow Transaction. In this table, I have 12 records. The picture below is the content of the table.
I have this SQL statement:
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
)
My objective is to update a request ID that has the OrderNumber of less than the maximum, which will be the output from the SELECT statement inside the WHERE clause. Now I expect that the records to be updated shall be only the said records (in the code, it's RequestId # 3).
What actually happened was instead of only four records being updated, it becomes five (5)! Is there a problem with my existing SQL statement?
Like SELECT , the UPDATE statement can have a subquery in several places or clauses. In an UPDATE , the two clauses in which subqueries are used most commonly are SET and WHERE . The SET clause is where we define the new value for the column being modified by the UPDATE .
You can use subqueries in SELECT, INSERT, UPDATE, and DELETE statements wherever expressions are allowed. For instance, you can use a subquery as one of the column expressions in a SELECT list or as a table expression in the FROM clause. A DML statement that includes a subquery is referred to as the outer query.
UPDATE operations with subqueries that reference the same table object are supported only if all of the following conditions are true: The subquery either returns a single row, or else has no correlated column references. The subquery is in the UPDATE statement WHERE clause, using Condition with Subquery syntax.
You can update the column specified in the SET clause with the value that a subquery returns. UPDATE orders SET ship_charge = (SELECT SUM(total_price) * . 07 FROM items WHERE orders.
Your problem is that you're doing an update of ALL records with RequestId = 3. Take into account that your subquery result is 3
so you end up updating all related records.
Your query is equivalent to do
UPDATE Workflow_Txn
SET Status = 1
WHERE RequestId = 3
Not sure if you have any reason to make your query more complex than it needs to be. Seems to me that something simpler would do the trick
UPDATE Workflow_Txn
SET Status = 1
WHERE [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)
AND RequestId = 3
The problem with your query is that the subquery goes into great detail to find the records with order number less than the maximum. And then it chooses everything with the same request -- which would include the maximum order number.
I prefer to fix this using a CTE as follows:
with toupdate as (
select t.*,
MAX(OrderNumber) as MaxON
from Workflow_txn
where RequestId = 3
)
UPDATE toupdate
SET Status = 1
where OrderNumber < MaxON;
I like this structure, because I can run the CTE separately to see what records are likely to be updated.
To fix your query, you would change the request to using OrderNumber
and repeat the 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
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With