UPDATE with EXISTS - sql

I'm testing this UPDATE statement to update all 4%, 8%, and 9% parts in our database. I'm trying to get the QTY_MULTIPLE value to match the CASES per layer value.
So, the REGEXP_LIKE, will eventually read:
> Regexp_like ( sp.part_no, '^4|^8|^9' )
It doesn't right now because I'm testing three specific parts. I want to make sure the rest of the statement works the way that it's supposed to.
Here's what I'm testing with:
UPDATE SALES_PART_TAB sp
SET sp.qty_multiple = ( SELECT cases_per_layer
FROM HH_INV_PART_CHARS
WHERE sp.part_no = HH_INV_PART_CHARS.part_no AND
sp.contract = HH_INV_PART_CHARS.contract )
WHERE Regexp_like ( sp.part_no, '^410-0017|^816-0210|^921-0003' ) AND
EXISTS
( SELECT sp.contract,
sp.part_no,
sp.qty_multiple,
HH_INV_PART_CHARS.cases_per_layer
FROM SALES_PART sp
inner join HH_INV_PART_CHARS
ON sp.part_no = HH_INV_PART_CHARS.part_no AND
sp.contract = HH_INV_PART_CHARS.contract
WHERE sp.qty_multiple != HH_INV_PART_CHARS.cases_per_layer );
When I run this statement, it updates 16 rows.
However, I'm expecting it to update 15 rows. I reached this conclusion by running the following SELECT statement:
SELECT sp.contract,
sp.catalog_no,
sp.qty_multiple,
HH_INV_PART_CHARS.cases_per_layer
FROM SALES_PART sp
inner join HH_INV_PART_CHARS
ON sp.part_no = HH_INV_PART_CHARS.part_no AND
sp.contract = HH_INV_PART_CHARS.contract
WHERE sp.qty_multiple != HH_INV_PART_CHARS.cases_per_layer AND
Regexp_like ( sp.part_no, '^410-0017|^816-0210|^921-0003' )
I think the problem I'm having is the UPDATE statement is updating all rows where the part_no and contract from the sales_part table exist on HH_INV_PART_CHARS. It's not limiting the update to part where the qty_multiple isn't equal to the cases_per_layer (which is what I want).
I'm a little stumped right now. I've been trying to work on both the subqueries but I'm not having any luck identifying where the problem is.

The Regexp_like ( sp.part_no,...) in the update query refers to SALES_PART_TAB.spart_no, while in the second query it refers to SALES_PART.spart_no.
One of the causes of the fog is that you redefine the alias sp in the same query, and so the exists subquery does not relate in any way to the record that is being updated. This means that if you would throw away the exists condition, you would still update 16 records. It seems very unlikely that this is what you want.
Use a different alias, so you can distinguish which table you want to refer to.

Related

update average/count from another table

I've been provided the below schema for this problem and I'm trying to do two things:
Update the ACCOUNT table's average_eval row with the average of the evaluation row from the POST_EVAL table per account_id.
Update the ACCOUNT table with a count of the number of posts per account_id, with default value 0 if the account_id has no post_id associated to it.
Here's the kicker : I MUST use the UPDATE statement and I'm not allowed to use triggers for these specific problems.
I've tried WITH clauses and GROUP BY but haven't gotten anywhere. Using postresql's pgadmin for reference.
Any help setting up these queries?
The first question can be done using something like this:
update account a
set average_eval = t.avg_eval
from (
select account_id, avg(evaluation) as avg_eval
from post_eval
group by account_id
) t
where t.account_id = a.account_id
The second question needs a co-related sub-query as there is no way to express an outer join in an UPDATE statement like the above:
update account a
set num_posts = (select count(*)
from post p
where p.account_id = a.account_id);
The count() will return zero (0) if there are no posts for that account. If a join was used (as in the first statement), the rows would not be updated at all, as the "join" condition wouldn't match.
I have not tested either of those statements, so they can contain typos (or even logical errors).
Unrelated, but: I understand that this is some kind of assignment, so you have no choice. But as RiggsFolly has mentioned: in general you should avoid storing information in a relational database that can be derived from existing data. Both values can easily be calculated in a view and then will always be up-to-date.

Very basic IF EXISTS statement not working

I really don't understand why my statement:
IF EXISTS (SELECT * FROM people WHERE ID = 168)
THEN SELECT * FROM people
END IF;
is returning this error:
Unknown statement type. (near "IF EXISTS" at position 0)
I'm using MariaDB 10.3. Any ideas?
ADDITIONAL INFO
This is of course a simplified example. What I wanna do is, concretely:
IF EXISTS (SELECT * FROM people WHERE ID = 168)
THEN UPDATE people SET calculated_value = complex_queries_and_calculations
WHERE ID = 168
.., so to update a field of a given record if that record contains a given data, and else do nothing.
To generate the data which would be used for the update, I need to query other tables for values and make some calculations. I want to avoid these queries + calculations, if there's actually nothing to update. And in this case, simply do nothing.
Hence, I guess that putting for example an EXIST clause inside a WHERE clause of the UPDATEstatement would end in many queries and calculations made in vain.
MySQL and MariaDB only allow IF statements in programming blocks -- stored functions, procedures, and triggers.
Instead, just use:
select p.*
from people p
where exists (select 1 from people p2 where p2.id = 168);
This returns all people if id 168 is in table.

How to delete only rows that comply with condition

I have the query below and the select return the rows that I want to delete but when I ran the entire query oh boy it deleted everything from the table.
How do I change the delete to only delete the rows returned by the select after the where:
delete from StaffSecurityItems
WHERE exists (
SELECT ssi.SysSaffID
FROM StaffDeparment sd, CustomFieldValues cfv, StaffSecurityItems ssi
where cfv.SysCustomFieldID = '-9223372036854749962'
and cfv.FieldValue = 'Yes'
and sd.SysStaffRoleID =11
and cfv.SysDeparmentID = sd.SysDeparmentID
and ssi.SysSaffID = SysSaffID
and ssi.ItemName in ('EnrollNewMember','EditEnrollmentInfo')
and ssi.SysStudyID ='-9223372036854759558');
My main issues is with the delete, I need to make sure that in only deletes what is being returned by select.
If the SELECT works, why not simply replace the SELECT? What you have there is a query that will delete every row in the table StaffSecurityItems if the query within the EXISTS returns even a single row (what rows it finds is meaningless, due to a lack of a correlated query).
DELETE SD
FROM StaffDeparment sd
JOIN CustomFieldValues cfv ON cfv.SysDeparmentID = sd.SysDeparmentID
JOIN StaffSecurityItems ssi ON ssi.SysSaffID = sd.SysSaffID --guessed alias
WHERE cfv.SysCustomFieldID = '-9223372036854749962'
AND cfv.FieldValue = 'Yes'
AND sd.SysStaffRoleID =11
AND ssi.ItemName in ('EnrollNewMember','EditEnrollmentInfo')
AND ssi.SysStudyID ='-9223372036854759558'
And, as mentioned in the comments, the ANSI-92 syntax has been around for 27 years! There's no reason you shouldn't be using it: Bad habits to kick : using old-style JOINs

Using a select statement as criteria for an update query

I'm trying to put together a query that updates a field within a table. I'm attempting to run a sub select query that gives me a number, and then use that number that resulted from the sub-query as part of the criteria for the update query.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] =[tbl_Foundation_Account].[Client_ID]
where ([tbl_Foundation_Account].[Foundation_Account_ID] =
(Select TOP 1 tbl_Foundation_Account.Foundation_Account_ID
FROM tbl_Foundation_Account
INNER JOIN [2_Import_tbl_AWCDSU]
ON tbl_Foundation_Account.Foundation_Account_ID =
[2_Import_tbl_AWCDSU].[ECPD Profile ID]))
My issue is I keep receiving this error
The multi-part identifier
tbl_Foundation_Account.Foundation_Account_ID" could not be bound.
Am I using the sub-query incorrectly? When I've received this error before, it's been because of some ambiguity in the table or field names, but this time I've checked for all that and it should be fine. Can anyone explain what SQL sin I have committed?
On the error
The multi-part identifier
tbl_Foundation_Account.Foundation_Account_ID" could not be bound.
This is because the table column [tbl_Foundation_Account].[Client_ID] does not exists in the scope of outer UPDATEquery .
The only table the outer query has an inkling about is [2_import_VZW_tbl_SMTN] and it does not have a column like [tbl_Foundation_Account].[Client_ID].
It is akin to writing a column name with a typo or like you said
When I've received this error before, it's been because of some
ambiguity in the table or field names
Please try a query like below.
Note that I am using Inner query syntax and ensuring that a single value is returned by using
select top 1 [Client_ID]
in the inner query. rest of the query syntax is same.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] =
(
select top 1 [Client_ID]
from [tbl_Foundation_Account]
where [Foundation_Account_ID] =
(
Select TOP 1 a.Foundation_Account_ID
FROM tbl_Foundation_Account a
INNER JOIN [2_Import_tbl_AWCDSU] b
ON a.Foundation_Account_ID = b.[ECPD Profile ID]
)
)
Another poster submitted this answer earlier, but then deleted it. I was able to try it before they deleted it and it works exactly how I needed it to work. I will use this as the right answer unless someone else can tell me why this is a bad Idea.
USE EMMS
Update [2_import_VZW_tbl_SMTN]
set [2_import_VZW_tbl_SMTN].[Client_ID] = [tbl_Foundation_Account].[Client_ID]
from [tbl_Foundation_Account]
where ([tbl_Foundation_Account].[Foundation_Account_ID] =
(Select TOP 1 tbl_Foundation_Account.Foundation_Account_ID
FROM tbl_Foundation_Account
INNER JOIN [2_Import_tbl_AWCDSU]
ON tbl_Foundation_Account.Foundation_Account_ID = [2_Import_tbl_AWCDSU].[ECPD Profile ID]))

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