How do I put an 'if clause' in an SQL string? - mysql

So here's what I want to do on my MySQL database.
I would like to do:
SELECT *
FROM itemsOrdered
WHERE purchaseOrder_ID = '#purchaseOrdered_ID'
AND status = 'PENDING'
If that would not return any rows, which is possible through if(dr.HasRows == false), I would now create an UPDATE in the purchaseOrder database:
UPDATE purchaseOrder
SET purchaseOrder_status = 'COMPLETED'
WHERE purchaseOrder_ID = '#purchaseOrder_ID'
How would I be able to make this process a little shorter?

For your specific query, you can do:
UPDATE purchaseOrder
SET purchaseOrder_status = 'COMPLETED'
WHERE purchaseOrder_ID = '#purchaseOrder_ID' and
not exists (SELECT *
FROM itemsOrdered WHERE purchaseOrder_ID = '#purchaseOrdered_ID' AND status = 'PENDING'
)
However, I might guess that you are looping at a higher level. To set all such values, try this:
UPDATE purchaseOrder
SET purchaseOrder_status = 'COMPLETED'
WHERE not exists (SELECT 1
FROM itemsOrdered
WHERE itemsOrdered.purchaseOrder_ID = purchaseOrder.purchaseOrdered_ID AND
status = 'PENDING'
limit 1
)

You can use the multiple-table UPDATE syntax to effect an ANTI-JOIN between purchaseOrder and itemsOrdered:
UPDATE purchaseOrder p LEFT JOIN itemsOrdered i
ON p.purchaseOrder_ID = i.purchaseOrder_ID
AND i.status = 'PENDING'
SET p.purchaseOrder_status = 'COMPLETED'
WHERE p.purchaseOrder_ID = '#purchaseOrder_ID'
AND i.purchaseOrder_ID IS NULL

Since MySQL doesn't support if exists(*Your condition*) (*Write your query*), you can achieve an 'if clause' by writing like this:
(*Write your insert or update query*) where not exists (*Your condition*)

You can also use the following query to check if the record exists and then update it:
if not exists(select top 1 fromFROM itemsOrdered
WHERE purchaseOrder_ID = '#purchaseOrdered_ID'
AND status = 'PENDING' )
Begin
UPDATE purchaseOrder
SET purchaseOrder_status = 'COMPLETED'
WHERE purchaseOrder_ID = '#purchaseOrder_ID
End

Select FROM t1
WHERE s11 > ANY
(SELECT col1,col2 FROM t2
WHERE NOT EXISTS
(SELECT * FROM t3
WHERE ROW(5*t2.s1,77)=
(SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM
(SELECT * FROM t5) AS t5)));

if not exists(select top 1 fromFROM itemsOrdered
WHERE purchaseOrder_ID = '#purchaseOrdered_ID'
AND status = 'PENDING' )
Begin
UPDATE purchaseOrder
SET purchaseOrder_status = 'COMPLETED'
WHERE purchaseOrder_ID = '#purchaseOrder_ID
End

after sql server 2008 provide Merge to insert,update and delete operation based on single match statement, also that allows you to join. below sample example might be helps you.
MERGE Target AS T
USING Source AS S
ON (T.EmployeeID = S.EmployeeID)
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%'
THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName)
WHEN MATCHED
THEN UPDATE SET T.EmployeeName = S.EmployeeName
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%'
THEN DELETE
OUTPUT $action, inserted.*, deleted.*;
like this you can insert, update and delete in one statements.
and for more information you can refer official documents on
https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx

If the table contains millions of records then the following query will work fast.
UPDATE PO
SET PO.purchaseOrder_status = 'COMPLETED'
FROM purchaseOrder PO
LEFT OUTER JOIN itemsOrdered IOD ON IOD.purchaseOrder_ID = PO.purchaseOrdered_ID and IOD.status = 'PENDING'
WHERE IOD.purchaseOrder_ID IS NULL

You can declare a variable holding the number of returned results on select query.
You can then run the update statement if this variable is more than 0
Declare #ResultCount int
SELECT #ResultCount = count(*) FROM itemsOrdered WHERE purchaseOrder_ID = '#purchaseOrdered_ID' AND status = 'PENDING'
If #ResultCount > 0
UPDATE purchaseOrder SET purchaseOrder_status = 'COMPLETED' WHERE purchaseOrder_ID = '#purchaseOrder_ID'

Related

How can I update a column value of a table in DB1 with a column value from a table in DB2?

I'm trying to perform a simple update in SQL between 2 tables from different DB's. The challenge is that in order for the value to be updated it must meet certain conditions. I have used the join statements to meet the conditions and when I go to test the value from table B it is not being updated into table A. Here is what I've done so far.
USE [dbo]
GO
CREATE PROCEDURE
(
#User_ID = INT,
#Batch_ID VARCHAR(32)
)
DECLARE #locid int
SELECT #locid
FROM OtherDB.dbo.User AS UL
WHERE UL.User_ID = #User_Id
and User_Type = 1;
UPDATE M
SET
M.Number = W.Number
FROM dbo.tableA AS W
JOIN dbo.tableB AS B ON B.ID = W.ID
JOIN dbo.tableC AS C ON C.ToolA = B.ToolA
JOIN dbo.tableD as D ON D.Zone = W.Zone_Name
JOIN OtherDB.dbo.tableMax AS M ON M.LID = #locid
AND M.Tool = C.Other_Tool
AND M.Zone = D._Other_Zone
AND M.Station = W.Station
WHERE W.User_ID = #User_ID
AND W.Batch_ID = #Batch_ID
SET NOCOUNT OFF;
The update statement is updating table M in otherDB, not table A on the current database.
You might revise the stored procedure to be
Update A
Set A.Number = W.Number
From dbo.tableA A
....

Update rows from multiple tables and

I am working on a project where I need to update 2 tables in a query.
I am doing this
UPDATE ward_beds a, ipd_patient_list b
SET
a.occupation_status = 'empty',
b.patient_status = 'Discharged'
WHERE
a.ward_id = b.ward_id AND b.patient_id = '4'
AND
b.appointment_id = '6' AND b.ward_id = '1'
so far it is working, now I want to update this
b.patient_status = 'Discharged'
on the row which is the last in all matching rows. I tried to put this
ORDER BY b.row_id DESC LIMIT 1
but it shows
#1221 - Incorrect usage of UPDATE and ORDER BY
error. How should I do it?
You can't use limit in this kind of update
but you could seach for the correct id using a subquery and join to the others tables
UPDATE ward_beds a
INNER JOIN (
select ward_id, max(row_id) last_id
from ipd_patient_list
group by ward_id
) t on t.ward_id = a.ward_id
INNER JOIN ipd_patient_list b ON a.ward_id = b.ward_id
AND b.patient_id = '4'
AND b.appointment_id = '6'
AND b.ward_id = '1'
AND b.row_id = t.last_id
SET a.occupation_status = 'empty',
b.patient_status = 'Discharged'

Update with SubQuery from same table

Is it possible to update using a subquery from the same table?
I get this error:
1093 - You can't specify target table 'tasks' for update in FROM clause
update tasks SET completed_form = 'y' AND all_forms_in = 'y' where EID in (select EID from tasks WHERE completed_form = 'y' AND all_forms_in = 'n' group by EID having count(*) > 1);
UPDATE
I found that if I wrapped the query in another select it worked. As referenced here: MySQL Error 1093 - Can't specify target table for update in FROM clause
update tasks SET all_forms_in = 'y' where EID in (SELECT * FROM (select EID from tasks WHERE completed_form = 'y' AND all_forms_in = 'n' group by EID having count(*) > 1)AS b);
MySQL supports JOIN in UPDATE statements, so you could do this without subqueries. You'd have to join to two distinct rows with your completed criteria to simulate the count(*) > 1.
UPDATE tasks AS t1
INNER JOIN tasks AS t2
ON (t1.EID = t2.EID AND t2.completed_form = 'y' AND t2.all_forms_in = 'n')
INNER JOIN tasks AS t3
ON (t1.EID = t3.EID AND t3.completed_form = 'y' AND t3.all_forms_in = 'n'
AND t2.primary_key <> t3.primary_key)
SET t1.completed_form = 'y',
t1.all_forms_in = 'y';

MySQL syntax for UPDATE + CASE WHEN + EXISTS + SELECT MAX

EDIT: Working now, solution in the bottom of this post.
I have tried to create this query for hours now, without success:
UPDATE tasks
SET `Order`=
(
CASE WHEN
(
SELECT EXISTS
(
SELECT 1
FROM user_job_tasks ujt
WHERE ujt.JobID = :jobID AND ujt.TaskID = LAST_INSERT_ID()
)
)
THEN
(
SELECT `order` FROM
(
SELECT MAX(t.`Order`)+1 AS `Order`
FROM user_job_tasks ujt
LEFT OUTER JOIN tasks t ON ujt.TaskID = t.ID
WHERE ujt.JobID = :jobID
) AS temp
)
ELSE
(
1
)
END
)
WHERE ID = LAST_INSERT_ID()
Now, the point of this is to update tasks table's column Order where ID equals something (LAST_INSERT_ID() here).
If any records exist in user_job_tasks where jobID and taskID match the values, I want to set Order as the highest value + 1 of Order found in user_job_tasks where jobID matches the value.
If not, Order will be set 1.
I am only getting an error General error: 1093 You can't specify target table 'tasks' for update in FROM clause. I fail to find anything wrong in the query syntax.
Sorry for confusing explanation, perhaps I should just go to sleep.
Working solution:
UPDATE tasks
SET `Order`=
(
COALESCE
(
(
SELECT `Order` FROM
(
SELECT MAX(t.`Order`)+1 AS `Order`
FROM user_job_tasks ujt
LEFT OUTER JOIN tasks t ON ujt.TaskID = t.ID
WHERE ujt.JobID = :jobID
) AS temp
),
1
)
)
WHERE ID = LAST_INSERT_ID()
I am not 100% sure this does what you want, but I think it does:
UPDATE tasks
SET `Order`= coalesce((SELECT MAX(t.`Order`) + 1 AS `Order`
FROM user_job_tasks ujt JOIN
tasks t
ON ujt.TaskID = t.ID
WHERE ujt.JobID = :jobID
), 1)
WHERE ID = LAST_INSERT_ID();
This just looks for the maximum id (+ 1) for your records and then uses 1 if this doesn't exist.
EDIT:
MySQL doesn't like using the table being updated in a from clause. So the above is correctly stated using a second subquery:
UPDATE tasks
SET `Order`= coalesce((SELECT `Order`
FROM (SELECT MAX(t.`Order`) + 1 AS `Order`
FROM user_job_tasks ujt JOIN
tasks t
ON ujt.TaskID = t.ID
WHERE ujt.JobID = :jobID
)
), 1)
WHERE ID = LAST_INSERT_ID();
This limitation would also apply to your query.

Update table on itself MySQL

I can't figure out how to make this query run.... I want to update the table so that dependent on the uuid it grabs the lowest of the 'last_updated' and updates the 'created_on' ... I keep getting 'cant specify target table' although I don't know why =/ Is it a recursion issue?
UPDATE dlp.address AS t1
SET created_on = (SELECT MIN(last_updated)
FROM dlp.address AS t2
WHERE t1.addressuuid = t2.addressuuid);
UPDATE dlp.address AS t1
INNER JOIN
(
SELECT addressuuid, MIN(last_updated) minDate
FROM dlp.address
GROUP BY addressuuid
) AS t2
ON t1.addressuuid = t2.addressuuid
SET t1.created_on = t2.minDate
You can use :
UPDATE dlp.address AS t1
, (SELECT addressuuid, MIN(last_updated) AS minDate
FROM dlp.address GROUP BY addressuuid) AS t2
SET t1.created_on = t2.minDate
WHERE t1.addressuuid = t2.addressuuid