在我的一个表字段中,我包含年龄范围。它们将采用
之类的格式27-51,18-28,10-17
37-55,60-70
1-5,11-16,30-32,60-90
etc
我正在尝试建立一个SELECT语句,我可以在其中搜索给定的年龄是否在任何范围内...类似
SELECT * from table where age IN (1-5,11-16,30-32,60-90)
但是它将在给定范围内搜索
如果我只有一个范围,则可以使用...
WHERE age
BETWEEN
SUBSTRING_INDEX(personsAge,"-",1) + 0 AND
SUBSTRING_INDEX(personsAge,"-",-1) + 0
但是如果我有多个范围怎么办?
答案 0 :(得分:1)
这是我在上面发表评论的答案。 我假设您可以创建一个函数:
注意:这是针对Sql Anywhere
的。请调整MySql
的语法(尤其是在切换参数的locate
函数)。该代码尚未准备就绪,因此我省略了一些有效性检查。我假设该列中的值均格式正确。
注意2 :这是有人向您转储糟糕的数据库设计并要求您解决问题的情况之一。请避免需要这种解决方案。
功能:
CREATE FUNCTION "DBA"."is_in_range"(age_range varchar(255), age int)
returns int
begin
declare pos int;
declare pos2 int;
declare strPart varchar(50);
declare strFrom varchar(10);
declare strTo varchar(10);
declare iFrom int;
declare iTo int;
while 1 = 1 loop
set pos = locate(age_range, ',');
if pos = 0 then
-- no comma found in the rest of the column value -> just take the whole string
set strPart = age_range;
else
-- take part of the sting until next comma
set strPart = substr(age_range, 1, pos - 1);
end if;
-- we are parsing the min-max part and do some casting to compare with an int
set pos2 = locate(strPart, '-');
set strFrom = substr(strPart, 1, pos2 - 1);
set strTo = substr(strPart, pos2 + 1);
set iFrom = cast(strFrom as int);
set iTo = cast(strTo as int);
if age between iFrom and iTo then
return 1;
end if;
-- if at end of age_range then quit
if pos = 0 then
return 0;
end if;
-- get the next part of the string after the comma
set age_range = substr(age_range, pos + 1);
set pos = locate(age_range, ',', pos);
end loop;
return 0;
end;
测试数据:
create local temporary table #tmpRanges (ident int, age_range varchar(255));
insert into #tmpRanges (ident, age_range) values (1, '27-51,18-28,10-17');
insert into #tmpRanges (ident, age_range) values (2, '37-55,60-70');
insert into #tmpRanges (ident, age_range) values (3, '1-5,11-16,30-32,60-90');
insert into #tmpRanges (ident, age_range) values (4, '1-50');
致电:
select * from #tmpRanges where is_in_range(age_range, 51) = 1;
select * from #tmpRanges where is_in_range(age_range, 10) = 1;
select * from #tmpRanges where is_in_range(age_range, 9) = 1;
etc...