I would create a secondary table and use it to drive the update.
Generally, try to parametrize things like this into tables, rather than making a big honking sql.
That still leaves you with the question of whether there is a contradiction in your criteria (i.e. multiple outcomes possible, no outcomes, etc...) but is cleaner in terms of sql and in terms of maintainability.
I've handled no outcome/multiple outcomes with exists and limit 1 below, respectively so that at least they don't error out.
drop table tgt;
create table tgt(a float, b float, calc int);
drop table range;
create table range(a_low float, a_high float,
b_low float, b_high float, calc float);
select * from tgt;
insert into tgt (a,b, calc) values(.32, .72, 0);
insert into tgt values(.41, .80, 0);
insert into tgt values(.28, .64, 0);
insert into tgt values(.31, .80, 0);
/*
3 < a < .4 and .71 < b < .83 = 1
.4 < a < .5 and .71 < b < .83 = 2
.2 < a < .3 and .58 < b < .77 = 3
*/
insert into range (a_low, a_high, b_low, b_high, calc)
values (.3, .4, .71, .83, 1);
insert into range (a_low, a_high, b_low, b_high, calc)
values (.4, .5, .71, .83, 2);
insert into range (a_low, a_high, b_low, b_high, calc)
values (.2, .3, .58, .77, 3);
select * from tgt;
update tgt
set calc =
(select calc
from range
where tgt.a
between range.a_low and range.a_high
and tgt.b between range.b_low and range.b_high
/* limit is to avoid
if error if multiple results
- picks only one
*/
limit 1)
where
/* and exists avoids it if there are no results */
exists
(select calc
from range
where tgt.a
between range.a_low and range.a_high
and tgt.b between range.b_low and range.b_high)
;
select * from tgt;
in postgresql this is the result:
0.32; 0.72; 1
0.41; 0.8; 2
0.28; 0.64; 3
0.31; 0.8; 1