postgresql – 使用比较运算符比较postgres中的字符串?
在许多编程语言中,您可以使用>,> =,<等运算符来比较字符串.等...语言将基于字母表中字母的位置进行比较. 例如在
PHP中
if ('a' < 'b') { echo 'Yes'; } else { echo 'No'; } > Yes 但是在postgres或mysql中 SELECT CASE WHEN 'a' < 'b' THEN 'yes' END FROM table Output: null 我有一个包含字符串的表,我需要通过SQL相互比较. 例如: 我想过使用正则表达式给一个字母分配一个数字,但是当没有字母时,这会打破比较. 你会如何在SQL中纯粹地解决这个问题? 解决方法
大多数字符串比较默认为所谓的
ASCIIbetical sorting.它将每个字符转换为其ASCII编号(或者可能是UTF-8,其与前7位的ASCII重叠)然后进行排序.这看起来很好……
select 'a' < 'z'; -- true ……但很快就会出错. select 'a' < 'Z'; -- false 这是因为所有大写字母都在ASCII和UTF-8中的所有小写字母之后. 解决这个问题的简单方法是通过在两侧调用upper或lower来规范化大小写. select lower('a') < lower('Z'); -- true ASCIIbetical排序的第二个问题是数字.再次,它开始很好…… select 'a9' < 'a1'; -- true ……但很快就去了锅. select 'a9' < 'a10'; -- false ASCIIbetical排序一次比较一个字符. ASCII 9(57)小于ASCII 1(49). 你想要的是一个natural sort,其中字符串部分作为字符串进行比较,数字作为数字进行比较.在SQL中进行自然排序并不是最简单的事情.您需要固定的字段宽度来分别对每个子字符串进行排序,或者可能需要使用正则表达式… 幸运的是,pg_natural_sort_order是Postgres扩展,实现了高效的自然排序. 如果您无法安装扩展,则可以使用存储过程,例如2kan的btrsort. CREATE FUNCTION btrsort_nextunit(text) RETURNS text AS $$ SELECT CASE WHEN $1 ~ '^[^0-9]+' THEN COALESCE( SUBSTR( $1,LENGTH(SUBSTRING($1 FROM '[^0-9]+'))+1 ),'' ) ELSE COALESCE( SUBSTR( $1,LENGTH(SUBSTRING($1 FROM '[0-9]+'))+1 ),'' ) END $$LANGUAGE SQL; CREATE FUNCTION btrsort(text) RETURNS text AS $$ SELECT CASE WHEN char_length($1)>0 THEN CASE WHEN $1 ~ '^[^0-9]+' THEN RPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[^0-9]+'),''),1,12),12,' ') || btrsort(btrsort_nextunit($1)) ELSE LPAD(SUBSTR(COALESCE(SUBSTRING($1 FROM '^[0-9]+'),' ') || btrsort(btrsort_nextunit($1)) END ELSE $1 END ; $$LANGUAGE SQL; 虽然它没有提供比较运算符,但我不会假装理解它.这允许您按顺序使用它. select * from things order by btrsort(whatever); 为防止自然排序的查询在大型桌子上变成泥,you can create a btree index on the result of that function. create index things_whatever_btrsort_idx ON things( btrsort(whatever) ); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |