Update Rows Where the following conditions are true - sql

I am attempting to overwrite a field value with the value from another table where a certain condition is true. I have mocked up my code below
Pseudocode:
Where an employee has the team Ops in old_data, get their new team from new_data and overwrite the team in old_data
My Code:
UPDATE old_data -- This has columns Employee, Latest_Team
SET
Latest_Team =
(select new_data.team
from new_data
left join old data
ON old_data.employee = new_data.employee
)
WHERE old_data.employee = 'Ops'
But this is returning the error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I'm not sure where i am going wrong exactly

If you are looking for the team "ops", then your query has several issues:
You are filtering on the employee, not the team.
You have a typo in the inner from clause.
You want a correlated subquery.
So, I think you want:
UPDATE old_data -- This has columns Employee, Latest_Team
SET Latest_Team = (select nd.team
from new_data nd
where old_data.employee = nd.employee
)
WHERE od.latest_team = 'Ops';
------^ I think this is the filter you describe

Make sure that this query doesnt return anyting and your code will work
select new_data.team, count(*)
from new_data
left join old data WHERE old_data.employee = 'Ops'
group by new_data.team
having count(*) > 1
If you have more than one team per employee with Old_data.employee = 'Ops', sql wont know which to choose for that employee for the update

You got a typo in your join - "old data" should be "old_data".
Maybe this can help you: update columns values with column of another table based on condition
In your example it would be:
UPDATE old_data SET
Latest_Team = (SELECT new_data.team FROM new_data WHERE old_data.employee = new_data.employee LIMIT 1)
WHERE old_data.employee = 'Ops';

Related

Division 2 lists distinct on 1 column

select * from ChallengeResults
where ResultPercentage =
(
select CorrectAnswers from ChallengeResults a
inner join Challenge b on b.ChallengeId = a.ChallengeId
and a.ChallengeType = '2'
)
/
(
select NumberOfQuestions
from ChallengeConfiguration a
inner join Challenge b on a.ChallengeConfigurationId = b.ChallengeConfigurationId
inner join ChallengeResults c on c.ChallengeId = b.ChallengeId
and c.ChallengeType = '2'
);
This is my query.
This is the error :
Msg 512, Level 16, State 1, Line 11
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I want to put the division of these two columns in a single column.
This is used to calculate the percentage of correct answers for a test.
I want it to return a value in the ResultPercentage column.
That error message is because your subqueries return multiple values but are used in a way such that the DB is expecting a single value.
It sounds like you want to return a column ResultPercentage based on a calculation. The correct place to do this is in the SELECT clause of your query, not the WHERE clause.
Without table structure and sample data it might not be possible to give you the correct answer, but you likely want something along the lines of:
select CorrectAnswers / NumberOfQuestions ResultPercentage, c.*
from ChallengeConfiguration a
inner join Challenge b on a.ChallengeConfigurationId = b.ChallengeConfigurationId
inner join ChallengeResults c on c.ChallengeId = b.ChallengeId
and c.ChallengeType = '2'
This is your second subquery on its own, but note the SELECT portion is altered. It will return a column named ResultPercentage that is obtained by dividing CorrectAnswers by NumberOfQuestions for each row.

SQL aggregation updates for some but not others

I am running this query which should take the sum of an amount from a table and if it <= 0, update the status of a different table from Active to Deactive. The query updates some values but not others. I have isolated to one observation where there are 3 payments that total 0 where it does not work.(123456789) What could be happening here? I am using sql query in Microsoft Access. Thank you.
UPDATE tbl_MASTER INNER JOIN tbl_Payments ON tbl_MASTER.DeviceID = tbl_Payments.DeviceID SET tbl_MASTER.ActiveDeactive = "DeActive"
WHERE tbl_Payments.Amount=(SELECT SUM(tbl_Payments.Amount) <= 0 FROM tbl_Payments) AND tbl__MASTER = '123456789';
Your query doesn't really make a lot of sense, to be honest. Where you have tbl_Payments.Amount=(SELECT SUM(tbl_Payments.Amount) <= 0 FROM tbl_Payments), that sub-query will just be summing up the "Amount" of every record in the table, regardless of which DeviceID. Plus, you're looking for one record in tbl_Payments table where the Amount = the sum of all of the Amounts in tbl_Payments??
I'd suggest that your query probably needs to be something more like this:
UPDATE tbl_MASTER SET tbl_MASTER.ActiveDeactive = "DeActive"
WHERE (SELECT SUM(tbl_Payments.Amount) FROM tbl_Payments WHERE tbl_Payments.DeviceID = tbl_MASTER.DeviceID) <= 0 AND tbl__MASTER = '123456789';
Currently, the subquery does not correlate specific IDs to outer query and also you specify <= 0 inside subquery's SELECT clause. Consider adjusting for IN clause with logic in a conditional HAVING and use table aliases to distinguish same named tables.
UPDATE tbl_MASTER AS m
INNER JOIN tbl_Payments AS p
ON m.DeviceID = p.DeviceID
SET m.ActiveDeactive = 'DeActive'
WHERE sub_p.DeviceID IN (
SELECT sub_p.DevideID
FROM tbl_Payments AS sub_p
GROUP BY sub_p.DeviceID
HAVING SUM(sub_p.Amount) <= 0
)

SQL update records in one table that satisify a query result on a related table

I'm trying to update a number of records in one table that are based on the result of a query from a related table. In this example, I have 150 records in tbl_events that I want to update with "entered_by", and in order to get those 150 records, I need to match the selection with the 150 records in tbl_locations has the value "needs update" in the notes field. The "Entered_by" value DOES NOT exist in tbl_locations, I'm just trying to update the table based on relationship pre-conditions. But I get the following error:
UPDATE TBL_EVENTS
SET Entered_By = 'Fred'
FROM GRSTBL_EVENTS as sp
JOIN TBL_LOCATIONS as so
On sp.Location_ID = so.Location_ID
AND so.Notes =(SELECT Notes from TBL_LOCATIONS where Notes = 'needs update')
Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated.
you can use in
UPDATE TBL_EVENTS
SET Entered_By = 'Fred'
FROM GRSTBL_EVENTS as sp
JOIN TBL_LOCATIONS as so
On sp.Location_ID = so.Location_ID
AND so.Notes in (SELECT Notes from TBL_LOCATIONS where Notes = 'needs update')
If I understand your data structures correctly then you need to update the entered_by field if there are any notes in the related tbl_locations table.
If so then the following, which is known as a correlated subquery should do what you want
UPDATE TBL_EVENTS
SET Entered_By = 'Fred'
WHERE EXISTS (
SELECT 1
FROM TBL_LOCATIONS
WHERE TBL_LOCATIONS.Location_ID = TBL_EVENTS.Location_ID
AND TBL_LOCATIONS.Notes = 'needs update'
)

Update multiple rows with sub query

I have two tables, UserStatus and User.
UserStatus has two fields:
Username,Status
User has two fields
Username, Deleted
This is the query I'm using
Update users
set deleted = '1'
where username = (select username
from tempDUDPIVOT
where status = 'inactive')
but get the error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I've tried a number of variations but can't figure out the solution... I have a feeling its very obvious.
Your help is appreciated.
Thanks.
The UPDATE syntax requires a scalar subquery. Using EXISTS (subquery) bring the parameters of the predicate closer together (i.e. makes the query easier to read and maintain, IMO) e.g.
UPDATE users
SET deleted = '1'
WHERE EXISTS (
SELECT *
FROM tempDUDPIVOT AS T1
WHERE T1.status = 'inactive'
AND T1.username = users.username
);
You could also use Standard SQL MERGE if your SQL product supports it (though note the parameters of the predicate further apart here):
MERGE INTO users
USING (
SELECT username
FROM tempDUDPIVOT
WHERE status = 'inactive'
) AS T1 (username)
ON T1.username = users.username
WHEN MATCHED THEN
UPDATE
SET users.deleted = '1';
Update users set deleted = '1'
where username IN (select username from tempDUDPIVOT where status = 'inactive')
IN accepts 0..inf values to be returned, and = accepts 1 and only one (not 0 or 42).

Doing an Update Ignore in SQL Server 2005

I have a table where I wish to update some of the rows. All the fields are not null. I'm doing a sub-query, and I wish to update the table with the non-Null results.
See Below for my final answer:
In MySQL, I solve this problem by doing an UPDATE IGNORE. How do I make this work in SQL Server 2005? The sub-query uses a four-table Join to find the data to insert if it exists. The Update is being run against a table that could have 90,000+ records, so I need a solution that uses SQL, rather than having the Java program that's querying the database retrieve the results and then update those fields where we've got non-Null values.
Update: My query:
UPDATE #SearchResults SET geneSymbol = (
SELECT TOP 1 symbol.name FROM
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE joiner.indelID = #SearchResults.id ORDER BY symbol.id ASC)
WHERE isSNV = 0
If I add "AND symbol.name IS NOT NULL" to either WHERE I get a SQL error. If I run it as is I get "adding null to a non-null column" errors. :-(
Thank you all, I ended up finding this:
UPDATE #SearchResults SET geneSymbol =
ISNULL ((SELECT TOP 1 symbol.name FROM
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE joiner.indelID = #SearchResults.id ORDER BY symbol.id ASC), ' ')
WHERE isSNV = 0
While it would be better not to do anything in the null case (so I'm going to try to understand the other answers, and see if they're faster) setting the null cases to a blank answer also works, and that's what this does.
Note: Wrapping the ISNULL (...) with () leads to really obscure (and wrong) errors.
with UpdatedGenesDS (
select joiner.indelID, name, row_number() over (order by symbol.id asc) seq
from
GeneSymbol AS symbol JOIN GeneConnector AS geneJoin
ON symbol.id = geneJoin.geneSymbolID
JOIN Result AS sSeq ON geneJoin.sSeqID = sSeq.id
JOIN IndelConnector AS joiner ON joiner.sSeqID = sSeq.id
WHERE name is not null ORDER BY symbol.id ASC
)
update Genes
set geneSymbol = upd.name
from #SearchResults a
inner join UpdateGenesDs upd on a.id = b.intelID
where upd.seq =1 and isSNV = 0
this handles the null completely as all are filtered out by the where predicate (can also be filtered by join predicate if You wish. Is it what You are looking for?
Here's another option, where only those rows in #SearchResults that are succesfully joined will be udpated. If there are no null values in the underlying data, then the inner joins will pull in no null values, and you won't have to worry about filtering them out.
UPDATE #SearchResults
set geneSymbol = symbol.name
from #SearchResults sr
inner join IndelConnector AS joiner
on joiner.indelID = sr.id
inner join Result AS sSeq
on sSeq.id = joiner.sSeqID
inner join GeneConnector AS geneJoin
on geneJoin.sSeqID = sSeq.id
-- Get "lowest" (i.e. first if listed alphabetically) value of name for each id
inner join (select id, min(name) name
from GeneSymbol
group by id) symbol
on symbol.id = geneJoin.geneSymbolID
where isSNV = 0 -- Which table is this value from?
(There might be some syntax problems, without tables I can't debug it)