Reputation: 41
How can I use CASE where it has multiple values? Here is my query:
UPDATE car_availability
SET availability_status = CASE
WHEN car_no = (SELECT A.car_no
FROM car_maintenance A
WHERE A.car_no = car_no
AND A.Start_Date = (SELECT DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0)))
THEN 'For Maintenance'
ELSE 'Good'
END
and I am getting an error
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.
In car_maintenance
table I have a set of cars where it is for maintenance while in car_availability
table I have all the cars. I want to set the availability_status
of all cars which is under car_maintenance
equal to 'For Maintenance'. How can I do that?
My columns in car_availability
are car_no
and car_availability
. Or can I do this using IF ELSE? Thanks in advance.
For car_maintenance
table, the columns are
car_no, maintenance_category, start_date_of_maintenance, end_date_of_maintenance
Upvotes: 1
Views: 353
Reputation: 1
I believe the error is actually occurring because your Sub Query is returning something other than a DISTINCT set of car numbers. I'm not sure, though, that merely adding in the "DISTINCT" key word will give proper results here.
In cases like this it can be very helpful to pull out the Subquery and look carefully just at that. Looking quickly at this, I see the Filter: "WHERE A.car_no = car_no", which I do not immediately understand. I'm trying to figure why that filtering would give us ONLY cars in maintenance now (I see the date stuff. . .which makes sense, but without knowing what's in the maintenance table we don't really know how to proceed). This Sub Query is dependent upon the exact contents of the maintenance table.
I'm thinking that what you want for a Sub query is an expression which correctly picks cars presently in maintenance, using data in the car_maintenance table. It's possible that you could do this by carefully considering what is in that table. If the table includes all cars which have ever been in maintenance, then, is there a field which shows CompletionDate? If your maintenance table shows both start and end dates for being within maintenance, then you are golden. You would need to do some date oriented statements, but could isolate which cars are currently in maintenance. It's even possible that any records with CompletionDate = NULL are those cars in maintenance. Again, we'd need to know a lot more about the car_maintenance table.
On the other hand, the car_maintenance table may be designed so it constantly changes, but only holds car_number, for those cars currently in maintenance.
We don't really know that, though. So, fill us in on what is in the car_maintenance table. We'd need to know more about that to help be sure your UPDATE query is going to cause the proper SET of "car_availability".
I'd tend to think we can view the code area of the Sub Query, as a "block" which is trying to yield up a list of cars. It's not all cars, but just SOME cars. Those which are presently in maintenance. That way, when you run your code for the Sub Query by itself (when I do this sort of thing, I just run it in the same SQL window, then cut and paste, ultimately removing the test code), you can look at it, and see: "Is this the current set of cars in maintenance?" Once you are satisfied the code always yields just those cars currently in maintenance, then it should be OK to place into code.
Good luck.
Upvotes: 0
Reputation: 1269873
Use join
. I think this is what you want:
UPDATE ca
SET availability_status = (CASE WHEN cm.car_no IS NOT NULL
THEN 'For Maintenance'
ELSE 'Good'
END)
FROM car_availability ca LEFT JOIN
car_maintenance cm
ON cm.car_no = ca.car_no AND
cm.Start_Date = CAST(GETDATE() as DATE);
Upvotes: 2
Reputation: 133370
You cold use an IN clause (instead of = )
UPDATE car_availability
SET availability_status = CASE WHEN car_no IN (SELECT A.car_no FROM car_maintenance A
WHERE A.car_no = car_no and A.Start_Date =
(SELECT DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0)))
THEN 'For Maintenance'
ELSE 'Good'
END
Upvotes: 1