0

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

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

blockCodeStart = "A25"
blockCodeEnd = "A39"

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

4

3 回答 3

0

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

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

('A' == 'A') and (25 == 39)
于 2013-10-03T18:26:03.643 回答
0

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

在此示例中,我创建并使用了 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
于 2013-10-03T18:54:10.133 回答
0

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

SQL小提琴

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 |
于 2013-10-03T19:26:52.153 回答