我必须使用包含数字文本的列值从表中选择数据,如下所示:
"SELECT Title, Category from BookList where CategoryField BETWEEN '"
+ blockCodeStart + "' AND '" + blockCodeEnd + "'";
blockCodeStart = "A25"
blockCodeEnd = "A39"
我理解这一点,并且只能处理文本或数字,但不能同时处理两者。任何帮助表示赞赏。
foo BETWEEN bar AND baz
只是一个方便的快捷方式bar <= foo AND foo <= baz
。如果您比较苹果和橙子,您不能期望得到“正常”的结果 - 因为您正在比较字符串,所以您会得到字符串结果。您不能指望数据库能够找出A25
大于A9
. 这不是人类。
您必须将字符串分解为它们各自的组件,然后将其作为“本机”值进行比较,例如
('A' == 'A') and (25 == 39)
如果字段类别中的所有值都具有相同的格式“字母”+“数字”,那么您可以创建比较类别的函数。
在此示例中,我创建并使用了 schema test
。
drop table if exists test.aaa;
drop function if exists test.natural_compare(s1 character varying, s2 character varying);
create or replace function test.natural_compare(s1 character varying, s2 character varying)
returns integer
as
$$
declare
s1_s character varying;
s2_s character varying;
s1_n bigint;
s2_n bigint;
begin
s1_s = regexp_replace(s1, '^([^[:digit:]]*).*$', '\1');
s2_s = regexp_replace(s2, '^([^[:digit:]]*).*$', '\1');
if s1_s < s2_s then
return -1;
elsif s1_s > s2_s then
return +1;
else
s1_n = regexp_replace(s1, '^.*?([[:digit:]]*)$', '\1')::bigint;
s2_n = regexp_replace(s2, '^.*?([[:digit:]]*)$', '\1')::bigint;
if s1_n < s2_n then
return -1;
elsif s1_n > s2_n then
return +1;
else
return 0;
end if;
end if;
end;
$$
language plpgsql immutable;
create table test.aaa (
id serial not null primary key,
categ character varying
);
insert into test.aaa (categ) values
('A1'),
('A2'),
('A34'),
('A35'),
('A39'),
('A355'),
('B1'),
('B6')
;
select * from test.aaa
where test.natural_compare('A34', categ) <= 0 and test.natural_compare(categ, 'A39') <= 0
这可能是一个很好的起点:
MySQL 5.5.32 架构设置:
create table BookList (
id int not null auto_increment,
Title varchar(10),
Category varchar(10),
CategoryField varchar(10),
primary key (id)
);
insert into BookList (title, Category, CategoryField) values
('Title1','CAT1','A2'),
('Title2','CAT2','A7'),
('Title3','CAT3','A10'),
('Title4','CAT4','A12'),
('Title5','CAT5','A25'),
('Title6','CAT6','A33'),
('Title7','CAT7','A39'),
('Title8','CAT8','A50'),
('Title6','CAT6','B33')
;
查询 1:
SELECT Title, Category
from BookList
where substring(CategoryField,1,1) = 'A' AND
CONVERT(substring(CategoryField,2), SIGNED) BETWEEN 25 AND 39
结果:
| TITLE | CATEGORY |
|--------|----------|
| Title5 | CAT5 |
| Title6 | CAT6 |
| Title7 | CAT7 |