当范围包含带有数字的文本时,BETWEEN运算符

时间:2013-10-03 18:21:31

标签: sql between

我必须使用包含带数字的文本的列值从表中选择数据,如下所示:

"SELECT Title, Category from BookList where CategoryField BETWEEN '"
  + blockCodeStart + "' AND '" + blockCodeEnd + "'";

blockCodeStart = "A25"
blockCodeEnd = "A39"

我理解并且只能处理文本或数字,但不能同时处理两者。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:0)

foo BETWEEN bar AND baz只是bar <= foo AND foo <= baz的便捷快捷方式。如果你比较苹果和橘子,你不能期望获得“正常”的结果 - 因为你正在比较STRINGS,你会得到字符串结果。您不能指望数据库能够确定A25大于A9。这不是人类。

您必须将字符串分解为各个组件,然后将其作为“本机”值进行比较,例如

('A' == 'A') and (25 == 39)

答案 1 :(得分:0)

如果字段Category中的所有值都具有相同的格式'LETTER'+'DIGITS',那么您可以创建比较类别的函数。

在此示例中,我创建并使用了架构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

答案 2 :(得分:0)

这可能是一个很好的起点:

SQL Fiddle

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

<强> Results

|  TITLE | CATEGORY |
|--------|----------|
| Title5 |     CAT5 |
| Title6 |     CAT6 |
| Title7 |     CAT7 |