如何按编号先查询,然后按字符串在同一字段中进行查询

时间:2013-07-27 15:30:37

标签: sql postgresql pattern-matching sql-order-by natural-sort

我在PostgreSQL 9.0中有一个数据库,它有一个带有字符串字段的表来存储客户端代码。 这些代码是字母数字,可以以字母或数字开头,例如1, 2, A0001-4, A0001-2, 10

我想首先订购数字,然后按字符串排序,例如

1, 2, 10, A0001-2, A0001-4

我使用to_number(fields, '99999999')执行此操作,例如:

SELECT * FROM empleados ORDER BY to_number(legajo, '99999999'), legajo

但是当代码与've'类似,没有数字时,查询失败。

我该怎么办?

3 个答案:

答案 0 :(得分:1)

您可以使用案例陈述来查找数字:

select *
from empleados
order by (case when legajo not similar to '%[^0-9]%' then 1 else 0 end) desc,
         (case when legajo not similar to '%[^0-9]%' then to_number(legajo, '999999999') end),
         legjo;

similar to表达式表示所有字符都是数字。

编辑:

修正了语法错误。你可以测试一下:

with empleados as (
      select 'abc' as legajo union all
      select '123'
     ) 
select *
from empleados
order by (case when legajo not similar to '%[^0-9]%' then 1 else 0 end) desc,
         (case when legajo not similar to '%[^0-9]%' then to_number(legajo, '999999999') end),
         legajo;

SQLFiddle是here

答案 1 :(得分:0)

试试这个:

select *
from empleados
order by
    case
        when legajo similar to '%[0-9]%' then to_number(legajo, '999999999')
        else 999999999
    end,
    legajo

sql fiddle demo

答案 2 :(得分:0)

WITH empleados(legajo) AS (
   VALUES
     ('A0001-4'::text)
    ,('123.345-56')
    ,('ve')
    ,('123')
    ,('123 ve')
   ) 
SELECT *
FROM   empleados
ORDER  BY CASE WHEN legajo ~ '\D' THEN 1000000000::int
                                  ELSE to_number(legajo, '999999999')::int END
      ,legajo;

~ is the regular expression operaor.
\D is the classs shorthand for non-digits.

legajo(legajo ~ '\D')中包含非数字字符的行会迟到。

-> SQLfiddle demo

Never use SIMILAR TO,这是一个毫无意义的操作员。