Multiple where exists - sql

I need to update value_check column in table_work as N based on below conditions
Update value_check as N
if employee_id in table_work has no employee_manager_id record
(either blank/null or no record at all) in employees_contact table
when getdate is between contact_eff_dt and contact_end_dt (join
using employee_id)
if employee_id in table_work has a record in
employees_contact table but employee_manager_id work_location_state
is not NJ or NY or ME ..mgr_work_location table has
employee_manager_id and work_location_state columns.
I am able to do it with 2 update statements bit is there a simple way to use only one update statement? Maybe using multiple where exists conditions?
Here are the 2 updates I use now:
UPDATE 1
Update work
set work.value_check = 'N'
From table_work work
Where wotk.value_check = 'Y'
And not exists (select employee_manager_id
from employees_contact contact
Where contact.employee_id = work.employee_id
And getdate() between contact.eff_dt and contact.end_dt)
UPDATE 2
Update work
set work.value_check = 'N'
From table_work work
Join employees_contact contact On contact.employee_id= work.employee_id
Join mgr_work_location mgr On mgr.mgr_id = contact.employee_manager_id
Where work.value_check = 'Y'
And getdate() between contact.eff_dt
and contact.end_dt And mgr.work_location_state not in ('NJ','NY,'ME')

The first query's NOT EXISTS criteria can probably be emulated in the second query via a LEFT JOIN, and check for contact.employee_id IS NULL (the unmatched)
And those limits on contact.eff_dt can be moved from the WHERE to that LEFT JOIN on mgr_work_location.
A test on rextester here
UPDATE work
SET work.value_check = 'N'
FROM table_work work
LEFT JOIN employees_contact contact
ON contact.employee_id = work.employee_id
AND contact.eff_dt <= getdate()
AND contact.end_dt >= getdate()
LEFT JOIN mgr_work_location mgr
ON mgr.mgr_id = contact.employee_manager_id
WHERE work.value_check = 'Y'
AND (contact.employee_id IS NULL
OR mgr.work_location_state NOT IN ('NJ','NY','ME'))

Related

SQL Oracle Update containing left join

I want to perform an update for the results of a select query.
SELECT
a.reason,
n.note
FROM applications a
LEFT JOIN notes n on n.app_id = a.app_id
AND n.note LIKE '%old%'
WHERE a.code = 'run' AND a.reason IS NULL
I thought I could perform these updates separately wrapping the select in an update however I get the error ORA-01733: virtual column not allowed here. How can I go about performing these updates?
UPDATE (
SELECT
a.reason AS Reason
FROM applications a
LEFT JOIN notes n on n.app_id = a.app_id
AND n.note LIKE '%old%'
WHERE a.code = 'run' AND a.reason IS NULL
) SET Reason = null
UPDATE (
SELECT
n.note AS Note
FROM applications a
LEFT JOIN notes n on n.app_id = a.app_id
AND n.note LIKE '%old%'
WHERE a.code = 'run' AND a.reason IS NULL
) SET Note = null
You can't update the two tables at the same time. You need two different update statements as follows:
Updating the APPLICATIONS table is quite easy as all the records of the APPLICATIONS table having a.code = 'run' AND a.reason IS NULL will be there in your SELECT query.
UPDATE APPLICATIONS A
SET
REASON = NULL
WHERE A.CODE = 'run'
AND A.REASON IS NULL;
To update the NOTES table, you can use the EXISTS clause as follows:
UPDATE NOTES N
SET
NOTE = NULL
WHERE EXISTS (
SELECT 1
FROM APPLICATIONS A
WHERE N.APP_ID = A.APP_ID
AND A.CODE = 'run'
AND A.REASON IS NULL
)
AND N.NOTE LIKE '%old%'
You must update the NOTES table first and then APPLICATIONS table as while updating the NOTES table you are using the condition A. REASON IS NULL but while updating the APPLICATIONS table, you are updating the REASON column.

Need Combined SQL Query to Update 2 Tables

I am having 2 tables. Table1 and Table2. I need to update these 2 tables based on some conditions.
The SQL select query from Table1 will return multiple records, let's
name it as SQLQuery1
From SQLQuery1 results returned I need to loop through each record and
execute another SQL query from Table2 which will return only 1
record, let's name it as SQLQuery2
Update Table1 and Table2 with the results returned from SQLQuery2.
Is there is a single query to combine the above operations?
If you need more information please let me know
UPDATE:
Following are the Sample Queries used,
SELECT E.Id,E.Name
from Employee E
where E.transdate > '2019-01-201 00:00:01' -- Multiple Results(SQLQuery1)
SELECT top 1 ED.Id,ED.balance
FROM EmployeeDetails ED
where ED.Name= #Name -- Single Results((SQLQuery2)
UPDATE Employee set IsProcessed=true
where Id=#Id
UPDATE EmployeeDetails set IsProcessed=true
where Id=#Id
I would use an UPDATE with an INNER JOIN. I have no idea if it's best practice at this point in time or whether there is a better way to do this but it works for the example I have created in dbfiddle.
Something like this:
UPDATE E
SET IsProcessed = 1
FROM Employee E
INNER JOIN EmployeeDetails ED ON E.Id = ED.Id
WHERE E.transdate >= '2019-01-20 00:00:01' AND ED.name = 'Martin'
UPDATE ED
SET IsProcessed = 1
FROM EmployeeDetails ED
INNER JOIN Employee E ON E.Id = ED.Id
WHERE E.transdate >= '2019-01-20 00:00:01' AND ED.name = 'Martin'
I used >= because I just set all 3 created records to the datetime you have and forgot that looking for a datetime greater than that would provide me with nothing. I also used a hard-coded name Martin instead of using a variable.
Here is my link to the dbfiddle I created in which I created Employee and EmployeeDetails, filled them with test data and then proceeded to identify the correct records using the date, time and name joined by their ID values:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=4492b27a9790f34b0bff0996e7fb6d36
Use INNER JOIN :
update e
set e.IsProcessed = 1 -- assuming BIT type
from employee e inner join
EmployeeDetails ed
on ed.name = e.name and ed.id = e.id
where e.transdate > '2019-01-201 00:00:01';
update ed
set ed.IsProcessed = 1 -- assuming BIT type
from EmployeeDetails ed inner join
Employee e
on ed.name = e.name and ed.id = e.id and
where e.transdate > '2019-01-201 00:00:01';
I wouldn't do it like this.
You can use outer apply to get rid of the cursor:
SELECT *
FROM T_Query1
OUTER APPLY
(
SELECT TOP 1 * FROM T_Query2
WHERE T_Query2.query1_id = T_Query1.id
) AS tQuery2
Then you can do an update like this:
UPDATE A
SET some_value = tQuery2.some_new_value
FROM T_Query1 AS A
OUTER APPLY
(
SELECT TOP 1 * FROM T_Query2
WHERE T_Query2.query1_id = A.id
) AS tQuery2
Besides that, you cannot update 2 tables with one update statement, AFAIK.
Your best bet would be
;WITH CTE AS
(
SELECT T_Query1.field1, T_Query2.field2, T_Query2.newField1
FROM T_Query1
OUTER APPLY
(
SELECT TOP 1 * FROM T_Query2
WHERE T_Query2.query1_id = T_Query1.id
) AS tQuery2
)
-- SELECT * FROM CTE
UPDATE CTE SET field1 = newField1, field2 = newField1
but I don't think CTE updating can handle outer-apply.

SQL Update a Column From a Select

I want to update 1 column (loadStatus) in the Loads table based on if another column (IBLoad) from a joined table is NULL. The end result when running my statement has 0 rows affected. I'm not sure what's wrong here but maybe my WHERE clause is incorrect?
This is the first time I've tried to update from a select so trying to figure it out :)
UPDATE Loads SET loadStatus = 'SCHEDULED'
FROM (
Select L.OID as [LoadID], T.IBLoad, L.loadStatus
From [Loads] L left join [Transaction] T on L.OID = T.IBLoad
Where T.IBLoad is null and load_type = 1 ) i
WHERE Loads.loadStatus = null
you do not need subquery, And use is null instead of = null
UPDATE L
SET loadStatus = 'SCHEDULED'
From [Loads] L left join [Transaction] T on L.OID = T.IBLoad
Where T.IBLoad is null and load_type = 1
and L.loadStatus is null
or use Loads.loadStatus = '' for empty string
You don't need to update from a select in this case. Here is another way to write the query:
UPDATE l
SET loadStatus = 'SCHEDULED'
FROM Loads l
WHERE l.loadStatus IS NULL AND
l.load_type = 1 AND
NOT EXISTS (SELECT 1 FROM [Transaction] t WHERE l.OID = t.IBLoad);

is there a way to update a column using multiple tables

I'm trying to update a column called Specialty in a table called #LIST. I need to pull information from 3 different tables incase the specialty in 1 table is NULL. I prefer to use the specialty from the #Segment table, if that's NULL then I want to use the specialty from the #SUBMARKET table, and if that's NULL I want to use the specialty from the #MARKET table.
When I run the below query, it doesn't update any rows. I don't want to use more than 1 Update statement. What can I do?
UPDATE #LIST
SET Specialty = CASE WHEN (l.Segment__c is not NULL) THEN s.Specialty
WHEN (l.Segment__c is NULL) THEN b.Specialty
WHEN (l.Submarket__c is NULL) THEN m.Specialty
ELSE s.Specialty
END
FROM #LIST l
join #MARKET m on m.Market = l.Market__c
join #SUBMARKET b on b.Submarket = l.Submarket__c
join #Segment s on s.Segment = l.Segment__c
You need to use the table alias in the UPDATE. Also, I think you need left join:
UPDATE l
SET Specialty = CASE WHEN (l.Segment__c is not NULL) THEN s.Specialty
WHEN (l.Segment__c is NULL) THEN b.Specialty
WHEN (l.Submarket__c is NULL) THEN m.Specialty
ELSE s.Specialty
END
FROM #LIST l
left join #MARKET m on m.Market = l.Market__c
left join #SUBMARKET b on b.Submarket = l.Submarket__c
left #Segment s on s.Segment = l.Segment__c;
Otherwise, the NULL values will filter out rows, because they do not match in the join.

SQL: Want to alter the conditions on a join depending on values in table

I have a table called Member_Id which has a column in it called Member_ID_Type. The select statement below returns the value of another column, id_value from the same table. The join on the tables in the select statement is on the universal id column. There may be several entries in that table with this same universal id.
I want to adjust the select statement so that it will return the id_values for entries that have member_id_type equal to '7'. However if this is null then I want to return records that have member_id_type equal to '1'
So previously I had a condition on the join (commented out below) but that just returned records that had member_id_type equal to '7' and otherwise returned null.
I think I may have to use a case statement here but I'm not 100% sure how to use it in this scenario
SELECT TOP 1 cm.Contact_Relation_Gid,
mc.Universal_ID,
mi.ID_Value,
cm.First_Name,
cm.Last_Name,
cm.Middle_Name,
cm.Name_Suffix,
cm.Email_Address,
cm.Disability_Type_PKID,
cm.Race_Type_PKID,
cm.Citizenship_Type_PKID,
cm.Marital_Status_Type_PKID,
cm.Actual_SSN,
cm.Birth_Date,
cm.Gender,
mc.Person_Code,
mc.Relationship_Code,
mc.Member_Coverage_PKID,
sc.Subscriber_Coverage_PKID,
FROM Contact_Member cm (NOLOCK)
INNER JOIN Member_Coverage mc (NOLOCK)
ON cm.contact_relation_gid = mc.contact_relation_gid
AND mc.Record_Status = 'A'
INNER JOIN Subscriber_Coverage sc (NOLOCK)
ON mc.Subscriber_Coverage_PKID = sc.Subscriber_Coverage_PKID
AND mc.Record_Status = 'A'
LEFT outer JOIN Member_ID mi ON mi.Universal_ID = cm.Contact_Gid
--AND mi.Member_ID_Type_PKID='7'
WHERE cm.Contact_Relation_Gid = #Contact_Relation_Gid
AND cm.Record_Status = 'A'
Join them both, and use one if the other is not present:
select bt.name
, coalesce(eav1.value, eav2.value) as Value1OrValue2
from BaseTable bt
left join EavTable eav1
on eav1.id = bt.id
and eav1.type = 1
left join EavTable eav2
on eav2.id = bt.id
and eav2.type = 2
This query assumes that there is never more than one record with the same ID and Type.