Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 使用比较运算符比较postgres中的字符串?_Postgresql_Natural Sort - Fatal编程技术网

Postgresql 使用比较运算符比较postgres中的字符串?

Postgresql 使用比较运算符比较postgres中的字符串?,postgresql,natural-sort,Postgresql,Natural Sort,在许多编程语言中,您可以使用诸如>、>=、

在许多编程语言中,您可以使用诸如>、>=、<等运算符来比较字符串,该语言将根据字母表中字母的位置进行比较

例如在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相互比较

例如: 6.25a 6.25b-这将大于6.25a 或 6.215-这将大于6.25a

我曾想过使用regexp为一个字母指定一个数字,但如果没有字母,这将破坏比较

纯粹在SQL中,您将如何处理这一问题?

注意:最初的答案有失偏颇

一个简单的比较可以对每个字符进行排序

select 'a1' < 'a9'; -- true because 'a' = 'a' and '1' < '9'.
虽然它没有提供比较运算符,我也不会假装理解它。这允许您按订单使用它

为了防止自然排序的查询在大型表上变成泥泞

只有当表为空时,才会输出任何内容。您不需要表来测试select语句

SELECT
CASE WHEN 'a' < 'b' THEN 'yes' END  -- yes

选择“a”<“b”;在postgres 9.6.1中,结果为真。选择“6.25a”<“6.25b”;返回True。选择“6.215”<“6.25a”;也返回True。最后一个是真的,因为6.2是匹配的。下一个字符“1”小于“5”,这使得6.215小于6.25a。这不是你的期望吗?好吧,实际上这似乎是问题所在。select“6.215”与“6.25a”的后一个比较返回true。直到你指出,我才注意到。因此,我想现在的问题是如何确保“15”大于“5a”可能首先测试字母,删除它们并测试数字字符串?这可能是一个很好的信息,不幸的是,这是一个封闭系统中运行的postgres。我无法安装扩展。@bakamike我使用存储过程添加了一个替代方法。在新的更新后,psql将提供选择“a”<“z”;同样正确的是,如果你更新你的answer@MichealToru选择“a”<“z”;这已经是事实了。你的意思是选择“a”<“Z”;?哪一次更新做出了改变?@MichealToru发现答案的前半部分是一条红鲱鱼。我把它剥掉了。谢谢你的来信。
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]+'), ''), 1, 12), 12, ' ') || btrsort(btrsort_nextunit($1))
            END
        ELSE
            $1
        END
      ;
$$ LANGUAGE SQL;
select * from things order by btrsort(whatever);
create index things_whatever_btrsort_idx ON things( btrsort(whatever) );
SELECT
  CASE WHEN 'a' < 'b' THEN 'yes' END
  FROM table
  Output: null
SELECT
CASE WHEN 'a' < 'b' THEN 'yes' END  -- yes