在ORDER BY子句中转换值

时间:2014-08-27 12:39:31

标签: sql postgresql type-conversion sql-order-by

考虑以下问题:

SELECT 1 AS a, '100' AS b
UNION
SELECT 1 AS a, '50' AS b
ORDER BY a, b;

导致:

a    b
1  '100'
1  '50'

我真正想要的是按数字而不是文字对b列进行排序。

一种可能的解决方案可能是:

SELECT 1 AS a, '100' AS b, '100'::int AS c
UNION
SELECT 1 AS a, '50' AS b, '50'::int AS c
ORDER BY a, c;

导致订购:

a    b     c
1  '50'   50
1  '100'  100

根据需要。

这非常令人满意,但如果我有1 mio。结果行然后我也有1 mio。在结果响应中传输的值,我不需要。

订购时是否有更简洁的方式转换列值?

我正在寻找一种让SQL服务器转换列值的方法"" ORDER BY条款,但仅返回"原文"结果列。

4 个答案:

答案 0 :(得分:1)

你可以用子查询做到这一点(认为联合是问题的一部分)。

select a, b
from (
      SELECT 1 AS a, '100' AS b
      UNION
      SELECT 1 AS a, '50' AS b)s
order by cast(b as int)-- or b::int

请参阅SqlFiddle,区别

但如果它只是一个样本,并且b是表格中的varchar类型,那么你可以

select a, b
from YourTable
order by a, cast(b as int)

没有任何子查询。

答案 1 :(得分:1)

处理字符串最好由字符串处理,如果该列中的任何值不能转换为整数,则会失败。

SELECT
      a, b
FROM (
      SELECT 1 AS a, '100' AS b
      UNION ALL
      SELECT 1 AS a, '50' AS b
      UNION ALL
      SELECT 1 AS a, 'badvalue' AS b
     ) s
ORDER BY
      a, right(concat('000000000',b),8)
;

| A |        B |
|---|----------|
| 1 |       50 |
| 1 |      100 |
| 1 | badvalue |

BUT:

SELECT
      a, b
FROM (
      SELECT 1 AS a, '100' AS b
      UNION ALL
      SELECT 1 AS a, '50' AS b
      UNION ALL
      SELECT 1 AS a, 'badvalue' AS b
     ) s
ORDER BY
      a, b::int
;

ERROR: invalid input syntax for integer: "badvalue": SELECT

http://sqlfiddle.com/#!15/d41d8/3109


编辑以回应领先的+/-负面字符

SELECT
      a, b
FROM (
      SELECT 1 AS a, '-100' AS b
      UNION ALL
      SELECT 1 AS a, '-50' AS b
      UNION ALL
      SELECT 1 AS a, '100' AS b
      UNION ALL
      SELECT 1 AS a, '50' AS b
      UNION ALL
      SELECT 1 AS a, 'badvalue' AS b
     ) s
ORDER BY
      a
    , case when left(b,1) = '-' then right(concat('000000000',b),8)
           else right(concat('11111111',replace(b,'+','')),8)
      end
;

http://sqlfiddle.com/#!15/d41d8/3112

答案 2 :(得分:0)

是或者只使用插入中的数字

SELECT 1 AS a, 100 AS b
UNION
SELECT 1 AS a, 50 AS b
ORDER BY a, b;

在插入前转换为数字,

SELECT 1 AS a, cast('100' as integer) AS b
UNION
SELECT 1 AS a, cast('50' as integer) AS b
ORDER BY a, b;

或按顺序

SELECT 1 AS a, 100 AS b
UNION
SELECT 1 AS a, 50 AS b
ORDER BY a, cast(b as integer); 

答案 3 :(得分:0)

投射列b值。

实施例

order by a, cast(b as numeric)