Postgres SQL SELECT and UPDATE behaving differently - sql

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';

Related

Oracle, update column in table 1, when related row does not exist in table 2

I have seen many answers that will update a table 1 when rows exist in table 2, but not one that works using a LEFT JOIN in selecting the rows, (for better performance). I have a solution to the update, but it will perform badly as it uses NOT IN.
So this SQL will update the tables as required, but looks to be very costly when run against large tables making it difficult to use.
update header
set status='Z'
where status='A'
and header.id not in (
select headerid
from detail
where detail.id between 0 and 9999999
);
Now I have a well performing query using a LEFT JOIN which returns the correct ids, but I have not been able to insert it into an update statement to give the same results.
The select statement is
select header.id
from header
left join detail on detail.headerid = header.id
where detail.headerid is null
and header.status='A'
So if I use this in the update statement as in:
update header
set status = 'Z'
where header.id = (
select header.id
from header
left join detail on detail.headerid = header.id
where detail.headerid is null and header.status='A'
)
Then I fail with:
ORA-01427: single-row subquery returns more than one row
I am expecting multiple header.id to be returned and want to update all these rows.
So I am still searching for a solution which will update the returned rows, using a well performing SQL select to return rows in table header, that do not have related rows in the detail table.
Any help would be appreciated, otherwise I will be left with the badly performing update.
Since you are expecting multiple header ID & the sub query returns multiple ID as you expected you should use IN
Try this
Update
header
Set status = 'Z'
Where
header.id IN (select
header.id
From
header
Left join
detail
On
detail.headerid = header.id
Where
detail.headerid is null
And
header.status='A')
I wouldn't put the condition on the outer table in the subquery. I am more comfortable writing this logic as:
update header h
set status = 'Z'
where not exists (select 1
from detail d
where d.headerid = h.id
) and
h.status = 'A';
If performance is an issue, indexes on detail(headerid) and header(status, id) and help.
typical, the next place I looked, I found an answer...
update header set status='Z' where not exists (select detail.headerid from detail where detail.headerid = header.id) and status = 'A'
Oh well, at least its here if anyone else wants to find it.
As the error states your subquery is returning more than one rows and you are using a = sign in your update query. = sign is not allowed if your query returns more than one records use either IN, NOT IN , EXISTS, NOT EXISTS as per your requirement

SQL Server : update using three tables

I'm a bit paranoid and novice when it comes to update scripts. Will this script work in SQL Server 2014?
I have entries in the country_code column in the address table I'd like to update, these entries are supplier addresses; and I only need to update where the terrority is Finland (You'll see that from the last line).
The script:
USE %dbname%
UPDATE [address_backup]
SET [address_backup].[country_code] = 'FI'
FROM [dbo].[address_backup]
LEFT JOIN [supplier_table] --Joins the Address table with the Supplier table
ON [address_backup].[addressid] = [supplier_table].[addressid]
LEFT JOIN [territory] --Join to the area table
ON [supplier_table].[territoryid] = [territory].[territoryid]
WHERE
[supplier_table].[deleted] <> '1' --Not Deleted
AND [territory].[territoryid] = '1000070' --Finland
I suspect it won't work?
Supposing frnachisees_territory to be territory yes, it works;
I would just check if all the JOINs are needed, since you use territoryid in the last one and then in the WHERE clause: could you avoid the last JOIN and use the supplier_table.territoryid for the WHERE?
EDIT: Possible script
USE %dbname%
UPDATE [address_backup]
SET [address_backup].[country_code] = 'FI'
FROM [dbo].[address_backup]
LEFT JOIN [supplier_table] --Joins the Address table with the Supplier table
ON [address_backup].[addressid] = [supplier_table].[addressid]
WHERE
[supplier_table].[deleted] <> '1' --Not Deleted
AND [supplier_table].[territoryid] = '1000070' --Finland
*I'd also swap LET JOIN with INNER JOIN as suggested by Juan Carlos Oropeza

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' );

sql query result returns asterisk "*" as column value

I'm trying to update a temporary table with multiple values from another table without using a join.
However, the query doesn't give any error but rather returns an asterisk as the value of the column. I have googled and asked some folks around the office but no one seems to have encountered this before or can offer explanation of why this could be happening.
update ##tempCLUnique set Total =
(
select COUNT(distinct u.unique_subs)
from tbl_Cluster_Cumm_Unique_Subs u
where u.cluster = ##tempCLUnique.cluster
)
Seems simple enough
Result Screen Grabhttp://i.stack.imgur.com/qE0ER.png
Use this
update ##tempCLUnique set Total = U.unique_subs
FROM ##tempCLUnique
INNER JOIN
(
select COUNT(distinct unique_subs)unique_subs
from tbl_Cluster_Cumm_Unique_Subs
)U
ON
u.cluster = ##tempCLUnique.cluster
Change the join according to your use.
Ashutosh

SQL Update with multiple INNER JOIN

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