SQL Update with multiple INNER JOIN - sql

I have two tables,
SELECT [SHADOW_ID]
,[DATA]
,[TSN]
,[HEALTH_PLAN_CATEGORY_VALUE_ID]
FROM [stbl834]
and
SELECT [HEALTH_PLAN_CATEGORY_VALUE_ID]
,[TSN]
FROM [uvwCLIENT_HEALTH_PLAN]
Right now HEALTH_PLAN_CATEGORY_VALUE_ID are all set to NULL in stbl834, I need to fetch these values from uvwCLIENT_HEALTH_PLAN based on different TSN values from stbl834. Is there a way to do this using JOIN statements? I need to avoid any sort of loops.

First run a select
SELECT *
FROM [stbl834] A
INNER JOIN [uvwCLIENT_HEALTH_PLAN] B ON A.TSN = B.TSN
and verify that you have correct number of rows and that the values in the columns match. this would ensure that you have a correct join key. If this looks correct use the below update
UPDATE [stbl834]
SET [HEALTH_PLAN_CATEGORY_VALUE_ID] = B.[HEALTH_PLAN_CATEGORY_VALUE_ID]
FROM [stbl834] A
INNER JOIN [uvwCLIENT_HEALTH_PLAN] B ON A.TSN = B.TSN

Select HEALTH_PLAN_CATEGORY_VALUE_ID, TSN
from stbl834 left join uvwCLIENT_HEALTH_PLAN
on stbl834.TSN=uvwCLIENT_HEALTH_PLAN.TSN
Do you need to insert them into stbl834? If so --
update stbl834
set HEALTH_PLAN_CATEGORY_VALUE_ID = uvwCLIENT_HEALTH_PLAN.HEALTH_PLAN_CATEGORY_VALUE_ID
from stbl834 left join uvwCLIENT_HEALTH_PLAN
on stbl834.TSN=uvwCLIENT_HEALTH_PLAN.TSN

Alternatively, you can do this for any RDBMS that does not support the UPDATE..FROM syntax:
UPDATE stbl834
SET health_plan_category_value_id = (SELECT health_plan_category_value_id
FROM uvwclient_health_plan
WHERE uvwclient_health_plan.tns = stbl834.tns)
This solution is SQL Ansi compatible, meaning it will work for any RDBMS. Please make sure the sub-query (SELECT) will only return record value for a given TNS, or else you will have to ensure that by using TOP or LIMIT (whatever is supported by your RDBMS).

You can try out this too, this might serve your purpose.
update stbl834
set stbl834.HEALTH_PLAN_CATEGORY_VALUE_ID= uvwCLIENT_HEALTH_PLAN.HEALTH_PLAN_CATEGORY_VALUE_ID
inner join uvwCLIENT_HEALTH_PLAN.TSN=HEALTH_PLAN_CATEGORY_VALUE_ID.TSN

Related

How do i perform a conditional update in SQL with data from multiple tables?

Trying to run an update on a column and i'm getting a syntax error on the FROM line connecting the tables
UPDATE inv_loc
SET inv_loc.product_group_id = 'TEMP'
WHERE inv_mast_ud.eh_spk LIKE '%T'
FROM
inv_mast_ud
left join inv_loc on inv_mast_ud.inv_mast_uid = inv_loc.inv_mast_uid
WHERE comes after FROM. I think you want:
UPDATE inv_loc
SET inv_loc.product_group_id = 'TEMP'
FROM inv_loc JOIN
inv_mast_ud
ON inv_mast_ud.inv_mast_uid = inv_loc.inv_mast_uid
WHERE inv_mast_ud.eh_spk LIKE '%T';
Note that I changed the LEFT JOIN to an INNER JOIN. You are updating inv_loc, so it makes no sense that that table is the second table in a LEFT JOIN.
I assume you actually want to filter the rows, so a LEFT JOIN is not needed. Otherwise, you would not need inv_mast_ud.
The WHERE clause belongs at the end of the update join statement:
UPDATE il
SET il.product_group_id = 'TEMP'
FROM inv_loc il
INNER JOIN inv_mast_ud imu
ON imu.inv_mast_uid = il.inv_mast_uid
WHERE
imu.eh_spk LIKE '%T';
See SQL update query using joins for a good canonical answer to your question.

Postgres SQL SELECT and UPDATE behaving differently

I can't see why the SELECT below finds 7065 records, but the update says it updates 13935 records, which is every record in the table.
Can anyone suggest why?
superfrr=# select count(*) from fromemailaddress LEFT JOIN email ON
(email.fromemailaddress = fromemailaddress.fromemailaddress)
WHERE LOWER(email.subject) ~ 'tester';
count
-------
7065
But:
superfrr=# update fromemailaddress set call=true from fromemailaddress
as fea LEFT JOIN email ON (email.fromemailaddress = fea.fromemailaddress)
WHERE LOWER(email.subject) ~ 'tester';
UPDATE 13935
The use of ~ suggests that you are using Postgres. If so, the two queries are doing very different things. In Postgres, you don't include the table being updated in the from clause.
So, I think you want:
update fromemailaddress
set call = true
from email
where email.fromemailaddress = fromemailaddress.fromemailaddress and
LOWER(email.subject) ~ 'tester';
Your version is updating all rows in fromemailaddress because there is no condition connecting fromemailaddress in the update clause and fea in the from clause.
Also note: the left join is unnecessary because the where clause turns it into an inner join anyway.
You must count on primary key it will returns all values because count do not work on null values. Hopes this helps thanks
select count(PrimaryKey Field) from fromemailaddress LEFT JOIN email ON
(email.fromemailaddress = fromemailaddress.fromemailaddress)
WHERE LOWER(email.subject) ~ 'tester';

Oracle SQL - How do I update from an Outer Joined Table?

The Problem
I need to write an Update query where my SET references an outer joined table.
I can do this fairly easily with SQL Server but I'm having a heck of a time figuring out the syntax in Oracle as I'm only allow a single table in an update query.
I have written the following Oracle query:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
WHERE EXISTS (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
AND tmp.sysind = 'AIM';
This takes care of the intersection but I need to deal with values in SalesExt_tmp that do not have equivalent matches in dw_sls_rep_conv (I plan to add a case statement to set null values to a default value). To do this I need to set up dw_sls_rep_conv as an outer joined table. But this is where I get stuck.
SQL Server Example
In SQL Server the solution is a piece of cake as you can have multiple tables in an Update Query:
UPDATE SalesExt_tmp tmp
LEFT JOIN dw_sls_rep_conv sls ON sls.aims_rep = tmp.slsrep
SET tmp.slsrep = sls.three_dig_rep
WHERE tmp.sysind = 'AIM';
But I can't for the life of me figure out how to do this in Oracle. I understand that this query will allow my slsrep field to be set to NULL in some occasions which causes me to fear that this operation may not be allowed.
Questions
1) Firstly is this possible in Oracle? (It's got to be, right?)
2) How do I need to restructure my query to pull this off? I'm guessing my WHERE EXISTS clause needs to go... but I'm still stuck as to where to place my JOIN.
If I understood you correctly, you want to set the value to NULL if there is no match in the dw_sls_rep_conv table? If so, just drop your EXISTS condition and all the rows will be updated:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
WHERE tmp.sysind = 'AIM';
If there is a match in the dw_sls_rep_conv table, then the slsrep column will be updated with selected value, otherwise, with NULL.
Have you considered using a subquery in your where clause that performs the outer join as you stated like this:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls WHERE sls.aims_rep = tmp.slsrep)
WHERE
tmp.rowid in
(SELECT tmp1.rowid
FROM SalesExt_tmp tmp1,
dw_sls_rep_conv sls
WHERE
tmp1.slsrep = sls.aims_rep (+)
AND tmp1.sysind = 'AIM' );

How can I prevent Duplicates from this SQL Statement?

I have two tables 1. tdppackages and 2. tpdstop and I do a SQL SELECT INNER JOIN to create a TableAdapter with some info from both and I want to NOT add duplicate records. Here is my SQL Statement:
SELECT tdppackages.trackno,
tdppackages.shpmentno,
tpdstop.custname,
tpdstop.address,
tpdstop.city,
tdppackages.amtdue,
tpdstop.pkgs,
tpdstop.ndx
FROM tpdstop
INNER JOIN tdppackages ON tpdstop.ndx = tdppackages.stopkey
Change SELECT to SELECT DISTINCT is the fastest way.
I think you would be having composite key which you should include in on clause.
like
INNER JOIN tdppackages ON tpdstop.ndx = tdppackages.stopkey
And tpdstop.col2 = tdppachages.col2
Do LEFT JOIN instead. Knowing the differences of each join would be very helpful moving forward.

SELECT subset from two tables and LEFT JOIN results

I'm trying to write a bit of SQL for SQLITE that will take a subset from two tables (TableA and TableB) and then perform a LEFT JOIN.
This is what I've tried, but this produces the wrong result:
Select * from TableA
Left Join TableB using(key)
where TableA.key2 = "xxxx"
AND TableB.key3 = "yyyy"
This ignore cases where key2="xxxx" but key3 != "yyyy".
I want all the rows from TableA that match my criteria whether or not their corresponding value in TableB matches, but only those rows from TableB that match both conditions.
I did manage to solve this by using a VIEW, but I'm sure there must be a better way of doing this. It's just beginning to drive me insane tryng to solve it now.
(Thanks for any help, hope I've explained this well enough).
YOu have made the classic left join mistake. In most databases if you want a condition on the table on the right side of the left join you must put this condition in the join itself and NOT the where clause. IN SQL Server this would turn the left join into an inner join. I've not used SQl lite so I don't know if it does the same but all records must meet the where clause generally.
Select *
from TableA
Left Join TableB on TableA.key = TableB.key
and TableB.key3 = "yyyy"
where TableA.key2 = "xxxx"