简体   繁体   中英

Update a column based on another column conditions

I have a typical requirement to validate a Column value[Target] against the Boundary values specified as min and max in other columns in the same Table.

Currently, I am doing the validation in 2 steps and making sure the target column value lies within the boundary limits. Can this be done with a single Update statement?

Below is the test data set:

CREATE TABLE rr_test
(
    minlimit INTEGER,
    maxlimit INTEGER,
    actualval INTEGER,
    calcval INTEGER
);

INSERT INTO rr_test
     VALUES (0,
             1000,
             500,
             NULL);

INSERT INTO rr_test
     VALUES (0,
             1000,
             2000,
             NULL);

INSERT INTO rr_test
     VALUES (2000,
             0,
             50,
             NULL);

INSERT INTO rr_test
     VALUES (2000,
             0,
             4000,
             NULL);

INSERT INTO rr_test
     VALUES (0,
             2000,
             50,
             NULL);

INSERT INTO rr_test
     VALUES (2000,
             4000,
             5000,
             NULL);

INSERT INTO rr_test
     VALUES (2000,
             4000,
             1000,
             NULL);

INSERT INTO rr_test
     VALUES (2000,
             4000,
             2000,
             NULL);

INSERT INTO rr_test
     VALUES (2000,
             4000,
             4000,
             NULL);

--To compare final results
UPDATE rr_test
   SET calcval = actualval;

Dataset at this point:

MINLIMIT    MAXLIMIT    ACTUALVAL     CALCVAL
0           1000            500         500
0           1000            2000        2000
2000        0               50          50
2000        0               4000        4000
0           2000            50          50
2000        4000            5000        5000
2000        4000            1000        1000
2000        4000            2000        2000
2000        4000            4000        4000 

--Update Target with Max Boundary
UPDATE rr_test
   SET calcval = maxlimit
 WHERE actualval > maxlimit;

--Update Target with Min Boundary
UPDATE rr_test
   SET calcval = minlimit
 WHERE calcval < minlimit;

Final Dataset:

MINLIMIT    MAXLIMIT    ACTUALVAL     CALCVAL
  0           1000        500           500
  0           1000        2000          1000
  2000        0           50            2000
  2000        0           4000          2000
  0           2000        50            50
  2000        4000        5000          4000
  2000        4000        1000          2000
  2000        4000        2000          2000
  2000        4000        4000          4000

Have you tried something like this?

UPDATE rr_test
   SET actualval =
        CASE
            WHEN actualval < minlimit THEN minlimit
            WHEN actualval > maxlimit THEN maxlimit
            ELSE actualval
        END;

Use a CASE expression:

UPDATE rr_test
SET calcval = CASE WHEN actualval > maxlimit THEN maxlimit
                   WHEN actualval < minlimit THEN minlimit END
WHERE
    actualval > maxlimit OR
    actualval < minlimit

I think this reproduces the logic of your original two updates. If the first update happened, then the second one would never happen. The second update could only happen if the first did not. The above CASE expression has the same behavior, since only condition can occur with each update.

Edit - if both conditions fire on the same row:

UPDATE rr_test
SET calcval = CASE WHEN actualval < minlimit THEN minlimit 
                   WHEN actualval > maxlimit THEN maxlimit END
WHERE
    actualval > maxlimit OR
    actualval < minlimit

I think I found a situation that does this in Single statement with the hints from above queries respecting all cases of Min and Max limits:

UPDATE rr_test
   SET actualval =
           CASE
               WHEN maxlimit > minlimit
               THEN
                   CASE
                       WHEN actualval > maxlimit THEN maxlimit
                       WHEN actualval < minlimit THEN minlimit
                       ELSE actualval
                   END
               WHEN maxlimit < minlimit
               THEN
                   minlimit
               WHEN maxlimit = minlimit
               THEN
                   CASE
                       WHEN actualval > maxlimit THEN maxlimit
                       WHEN actualval < maxlimit THEN minlimit
                       ELSE actualval
                   END
           END;

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