简体   繁体   中英

UPDATE CASE SQL Server with conditions

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

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM