我有一个如下所示的MySQL数据集:
a b
.32 .72
.41 .80
.28 .64
.31 .80
我想根据a和b的条件为每一行分配值( c ):
.3< a< .4和.71< b< .83 = 1
.4< a< .5和.71< b< .83 = 2
.2< a< .3和.58< b< .77 = 3
等等。这会导致我的表格看起来像这样:
a b c
.32 .72 1
.41 .80 2
.28 .64 3
.31 .80 1
我该怎么做?我已经尝试了一个案例,当时()声明但是没有用,因为我不知道如何/如果有可能有一个有多个案例的那个。
答案 0 :(得分:2)
我不完全理解这一点:我在()语句中尝试了一个案例,但由于我不知道如果有可能有一个多于一个案例。
这将为您提供您描述的输出。我有点懒/累,所以我只是粘贴SQL Fiddle的输出:
MySQL 5.5.32架构设置:
CREATE TABLE Table1
(`a` decimal(2,2), `b` decimal(2,2))
;
INSERT INTO Table1
(`a`, `b`)
VALUES
(.32, .72),
(.41, .80),
(.28, .64),
(.31, .80)
;
alter table table1 add column c int;
update table1
set c =
case
when (.3 < a and a < .4) and (.71 < b and b < .83) then 1
when (.4 < a and a < .5) and (.71 < b and b < .83) then 2
when (.2 < a and a < .3) and (.58 < b and b < .77) then 3
end;
查询1 :
select * from table1
<强> Results 强>:
| A | B | C |
|------|------|---|
| 0.32 | 0.72 | 1 |
| 0.41 | 0.8 | 2 |
| 0.28 | 0.64 | 3 |
| 0.31 | 0.8 | 1 |
答案 1 :(得分:1)
您不会说出您正在使用的SQL实现。
如果您正在使用SQL Server,则可以添加计算列,如下所示:
create table foo
(
int a not null ,
int b not null ,
c as case
when a > 0.3 and a < 0.4 and b > 0.71 and b < 0.83 then 1
when a > 0.4 and a < 0.5 and b > 0.71 and b < 0.83 then 2
when a > 0.2 and a < 0.3 and b > 0.58 and b < 0.77 then 3
else null // anything that doesn't match one of the above tests
end ,
)
如果你不能做那样的话,你可以创建一个视图:
create table foo
(
int a not null ,
int b not null ,
)
create view foo_view as
select foo.* ,
case
when a > 0.3 and a < 0.4 and b > 0.71 and b < 0.83 then 1
when a > 0.4 and a < 0.5 and b > 0.71 and b < 0.83 then 2
when a > 0.2 and a < 0.3 and b > 0.58 and b < 0.77 then 3
else null // anything that doesn't match one of the above tests
end as c
确保您的计算c
始终与基础数据同步。
如果你采用更新路线,那么这个版本就不那么难了:
update foo
set c = case
when a > 0.3 and a < 0.4 and b > 0.71 and b < 0.83 then 1
when a > 0.4 and a < 0.5 and b > 0.71 and b < 0.83 then 2
when a > 0.2 and a < 0.3 and b > 0.58 and b < 0.77 then 3
else null // anything that doesn't match one of the above tests
end
虽然您可以考虑在表格上添加更新触发器,以自动更新c
,然后a
或b
更改值。
答案 2 :(得分:1)
我会创建一个辅助表并使用它来驱动更新。
一般来说,尝试将这样的事情参数化为表格,而不是制作一个大的鸣叫sql。
这仍然留给您一个问题,即您的标准是否存在矛盾(即可能有多种结果,没有结果等等),但在sql和可维护性方面更清晰。
我已经分别处理了存在和下限1的结果/多个结果,因此至少他们不会出错。
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;
在postgresql中这是结果:
0.32; 0.72; 1
0.41; 0.8; 2
0.28; 0.64; 3
0.31; 0.8; 1