Update multiple rows with sub query - sql

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).

Related

Update Rows Where the following conditions are true

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

Setting subquery to variable to be used within the IN operator

I would like to use a variable to represent a result set that will be used in the WHERE clause of a query.
SELECT *
FROM Table1
WHERE
Exam1_ID IN (SELECT Id FROM Exam)
OR Exam2_ID IN (SELECT Id FROM Exam)
OR Exam3_ID IN (SELECT Id FROM Exam)
OR Exam4_ID IN (SELECT Id FROM Exam)
I would like to use a variable in place of SELECT Id FROM Exam so I don't have to keep repeating the query. I tried declaring a variable but since the results of the subquery could contain multiple integers I am not sure what the declare the variable as. I went ahead and tried ...
DECLARE #SubQuery INT;
SET #SubQuery = (SELECT Id FROM Exam);
SELECT *
FROM Table1
WHERE
Exam1_ID IN (#SubQuery)
OR Exam2_ID IN (#SubQuery)
OR Exam3_ID IN (#SubQuery)
OR Exam4_ID IN (#SubQuery)
I received the following error ..
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
You'd probably find that this performs better using a WHERE EXISTS like this
SELECT *
FROM Table1 t1
WHERE EXISTS ( SELECT *
FROM Exam e
WHERE t1.Exam1_ID = e.Id
OR t1.Exam2_ID = e.Id
OR t1.Exam3_ID = e.Id
OR t1.Exam4_ID = e.Id)
You can write an exists like this.
SELECT *
FROM Table1 t1
WHERE EXISTS (
SELECT 1 FROM Exam e
WHERE e.Id in ( t1.Exam1_ID , t1.Exam2_ID , t1.Exam3_ID, t1.Exam4_ID )
)
Lets begin from error message
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
The reason is pretty simple, you declared your subquery as INT
So if you will change it to TABLE(Id INT) you will receive new error message.
You can use different ways to solve your problem.
1) Inner join (It can give you duplicates, so I dont know is it valid for you to use this method)
DECLARE #SubQuery TABLE (RecordId INT)
INSERT INTO
#SubQuery
SELECT
Id
FROM
Exam
SELECT *
FROM
Table1 t1
INNER JOIN #Subquery sq
ON sq.Id = t1.Exam1_ID
OR sq.Id = t1.Exam2_ID
OR sq.Id = t1.Exam3_ID
OR sq.Id = t1.Exam4_ID
2) Exist
Please find sample in Rich Benner answer. He posted it while I was typing. But I found one typo there, he used different aliases in exists block
OR t1.Exam2_ID = e.Id --t1 - correct alias
OR t2.Exam2_ID = e.Id --t2 - incorrect
OR t3.Exam2_ID = e.Id --t3 - incorrect
OR t4.Exam2_ID = e.Id --t4 - incorrect

How to update column value based on records existing in two different tables?

Is there a better way of doing the following? (Instead of having two separate queries) I want to update the UserTypeId column to either 'USER1'
or 'USER2' if a record exists in the AdminDetails table.
UPDATE Usernames
SET UserTypeId = (select Id from UserTypes where code = 'USER1')
WHERE EXISTS
(SELECT AdminDetails.Id
FROM AdminDetails
WHERE AdminDetails.Id = Usernames.Id)
UPDATE Usernames
SET UserTypeId = (select Id from UserTypes where code = 'USER2')
WHERE EXISTS
(SELECT AdminDetails.Id
FROM AdminDetails
WHERE AdminDetails.Id = Usernames.Id)
I tried using COUNT() but I got the following error when attempting to do this in one query using an inner join and case statement:
UPDATE Usernames
SET UserTypeId = (CASE WHEN COUNT(AdminDetails.Id) > 0 THEN 'USER1' ELSE 'USER2' END)
FROM AdminDetails
INNER JOIN Usernames AS un
ON AdminDetails.Id = un.UserId
But it gives the following error: 'An aggregate may not appear in the set list of an UPDATE statement'.
I want to do this in one query using case when then else by checking if a record exists. How can I do this?
You can try something like this, using EXISTS within the CASE statement:
UPDATE Usernames
SET UserTypeId = (CASE WHEN EXISTS
(SELECT AdminDetails.Id
FROM AdminDetails
WHERE AdminDetails.Id = Usernames.Id)
THEN 'USER1' ELSE 'USER2' END)
NOTE: This would update all records where the IDs are in both tables unless you add a WHERE clause on to it. Also, I'm not sure that you would want to update the UserTypeId with the values USER1 and USER2, which is what your third UPDATE statement is trying to do. Without seeing your full database schema it's hard to be exact.

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

How to write a select Query inside a CASE condition in MS SQL

I have an Sql Query. It does not have any compilation error but in runtime it shows
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
SELECT a.UserID FROM USERGROUPS a WHERE a.GroupID IN
(CASE WHEN #group_id IS NULL THEN (select groupid from usergroups) ELSE
CASE WHEN #group_id=0 THEN (select groupid from usergroups where userid = #userid)ELSE
#group_id END END )
Thanks in advance.
Try this instead:
SELECT a.UserID
FROM USERGROUPS a
WHERE
(#groupid is NUll and a.GroupID IN (select groupid from usergroups))
or (#groupid = 0 and a.GroupID IN (select groupid from usergroups where (userid = #userid)))
or a.GroupID IN (#groupid)
according to the MSDN
[Case] evaluates a list of conditions and returns one of multiple possible
result expressions.
basically you can use a SELECT within a CASE, but it only has to return one single result and not a list (which is something that can only be evaluated at runtime, that's why your query results formally correct but fails when you launch it)
If you tell us some more about what you're trying to do, maybe I can help you rewrite your query