创建表和准备数据
CREATE TABLE customer
(
customer_id serial ,
title char(4) ,
fname varchar(32) ,
lname varchar(32) NOT NULL,
addressline varchar(64) ,
town varchar(32) ,
zipcode char(10) NOT NULL,
phone varchar(16) ,
CONSTRAINT customer_pk PRIMARY KEY(customer_id)
);
(
customer_id serial ,
title char(4) ,
fname varchar(32) ,
lname varchar(32) NOT NULL,
addressline varchar(64) ,
town varchar(32) ,
zipcode char(10) NOT NULL,
phone varchar(16) ,
CONSTRAINT customer_pk PRIMARY KEY(customer_id)
);
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Miss','Jenny','Stones','27 Rowan Avenue','Hightown','NT2 1AQ','023 9876');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Andrew','Stones','52 The Willows','Lowtown','LT5 7RA','876 3527');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Miss','Alex','Matthew','4 The Street','Nicetown','NT2 2TX','010 4567');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Adrian','Matthew','The Barn','Yuleville','YV67 2WR','487 3871');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Simon','Cozens','7 Shady Lane','Oakenham','OA3 6QW','514 5926');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Neil','Matthew','5 Pasture Lane','Nicetown','NT3 7RT','267 1232');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Richard','Stones','34 Holly Way','Bingham','BG4 2WE','342 5982');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mrs','Ann','Stones','34 Holly Way','Bingham','BG4 2WE','342 5982');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mrs','Christine','Hickman','36 Queen Street','Histon','HT3 5EM','342 5432');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Mike','Howard','86 Dysart Street','Tibsville','TB3 7FG','505 5482');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Dave','Jones','54 Vale Rise','Bingham','BG3 8GD','342 8264');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Richard','Neill','42 Thatched Way','Winersby','WB3 6GQ','505 6482');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mrs','Laura','Hardy','73 Margarita Way','Oxbridge','OX2 3HX','821 2335');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','Bill','O\'Neill','2 Beamer Street','Welltown','WT3 8GM','435 1234');
INSERT INTO customer(title, fname, lname, addressline, town, zipcode, phone)
VALUES('Mr','David','Hudson','4 The Square','Milltown','MT2 6RT','961 4526');
使用 BETWEEN 比较字符串。假设我们想获得一个首字母为 B 和 N 之间的所有不同城镇的列表。我们可以依照以下的写法:
SELECT DISTINCT town FROM customer WHERE town BETWEEN 'B' AND 'N';

从上图结果,我们发现现这个 SQL 没有达到如期的效果。Newtown 没有被列出来,而它是以字母 N 开始的。
这条语句没有达到我们效果的原因是依照 SQL 标准,用填充你给的字符串到需要比较的字符串的长度然后再比较。所以当我们比较 Newtown 的时候,用“N ”(N 后面填充了六个空白)和 Newtown,而空 白在 ASCII 表中的位置再其他所有字符之前,所以判断的结果是 Newtown 比“N ”大,所以它不应该在结果列表中.
解决方法
SELECT DISTINCT town FROM customer WHERE town BETWEEN 'B' AND 'Nz';

注意我们没有在 B 之后加上 z,因为 B 后添加空格确实能匹配到 B 开头的所有城镇,因为它是一个开始点而不是结束点。还要注意如果一个城镇开始于字符 Nzz,我们仍将无法找到它,因为我们将用“Nz ”与 Nzz 比较,然后确定 Nzz 在 Nz 之后,因为字符串 Nz 字符串依旧被填充了一个空白,而空白的位置比我们比较的字符串相对位置的字符 z 的位置靠前。
这种比较确实有一些很微妙的行为,所以如果你确实要使用 BETWEEN 比较字符串,需要仔细考虑关于需要匹配的 内容。
本文探讨了在使用BETWEEN AND操作符进行字符串比较时遇到的问题,例如在SQL查询中未正确筛选出首字母位于B和N之间的数据。以Newtown为例,尽管它以N开头,但并未出现在预期的结果中。文章将揭示这个问题的原因并提出解决方案。
2021

被折叠的 条评论
为什么被折叠?



