ORACLE varchar字段中有汉字和数字,根据数字 order by

在项目中遇到根据varchar字段中的数字排序的问题,由于数据类型是varchar,导致'9'出现在'10'之后。解决方案包括:将字段改为int类型,或者在SQL查询中使用to_number()函数对varchar字段进行转换后再排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中有个需求是根据收款方来分类计算小计,并进行排序.

发现排序那一列中有小计和数字的时候,因为都是verchar类型的,所以进行排序之后发现9是在排在了10后面的.

SELECT *
  FROM (
        
        SELECT 1 AS SNO,
                TO_CHAR(ROW_NUMBER() OVER(ORDER BY DI.DISTRIBUTOR_NAME)) NUM,
                DI.DISTRIBUTOR_NAME,
                LCC.HANDLING_CHARGE_MONEY
          FROM LB_CONTRACT_INFO LCI
          LEFT JOIN LC_CALC_CONDITION LCC
            ON LCI.ID = LCC.CONTRACT_ID
          LEFT JOIN DISTRIBUTOR_INFO DI
            ON DI.ID = LCI.DISTRIBUTOR_ID
         WHERE LCI.ID IN ()
        UNION ALL
        SELECT 2 AS SNO,
                '小计' NUM,
                DI.DISTRIBUTOR_NAME,
                SUM(HANDLING_CHARGE_MONEY) AS HANDLING_CHARGE_MONEY
          FROM LB_CONTRACT_INFO LCI
          LEFT JOIN LC_CALC_CONDITION LCC
            ON LCI.ID = LCC.CONTRACT_ID
          LEFT JOIN DISTRIBUTOR_INFO DI
            ON DI.ID = LCI.DISTRIBUTOR_ID
         WHERE LCI.ID IN ()
         GROUP BY DI.DISTRIBUTOR_NAME) T
 ORDER BY DISTRIBUTOR_NAME, SNO, NUM

结果为:

后sql修改为:

SELECT *
  FROM (SELECT T.*, DECODE(NUM, '小计', '99999999', NUM) ORDER_COLUMN
          FROM (SELECT 1 AS SNO,
                       TO_CHAR(ROW_NUMBER()
                               OVER(ORDER BY DI.DISTRIBUTOR_NAME)) NUM,
                       DI.DISTRIBUTOR_NAME,
                       LCC.HANDLING_CHARGE_MONEY
                  FROM LB_CONTRACT_INFO LCI
                  LEFT JOIN LC_CALC_CONDITION LCC
                    ON LCI.ID = LCC.CONTRACT_ID
                  LEFT JOIN DISTRIBUTOR_INFO DI
                    ON DI.ID = LCI.DISTRIBUTOR_ID
                 WHERE LCI.ID IN ()
                UNION ALL
                SELECT 2 AS SNO,
                       '小计' NUM,
                       DI.DISTRIBUTOR_NAME,
                       SUM(HANDLING_CHARGE_MONEY) AS HANDLING_CHARGE_MONEY
                  FROM LB_CONTRACT_INFO LCI
                  LEFT JOIN LC_CALC_CONDITION LCC
                    ON LCI.ID = LCC.CONTRACT_ID
                  LEFT JOIN DISTRIBUTOR_INFO DI
                    ON DI.ID = LCI.DISTRIBUTOR_ID
                 WHERE LCI.ID IN ()
                 GROUP BY DI.DISTRIBUTOR_NAME) T) TT
 ORDER BY DISTRIBUTOR_NAME, SNO, TO_NUMBER(ORDER_COLUMN)

结果可以正常排序:

 

1、数据库字段为int类型:

使用order by 排序:

SELECT * FROM test22 ORDER BY ID;

 结果为:

2、数据库字段为varchar类型:

使用order by 排序 结果为:

可以看出,varchar 类型字段排序时,9>5>11>10>1

先是比较了第一位的数,然后才去比较第二位的数

3、解决办法:

 1)可以将数据库字段修改为int类型

 2)如果不能修改数据库字段,可以将sql修改为如下(在字段后面加一个0)

 3)order by 中varchar字段 加上to_number()函数

SELECT * FROM test22  ORDER BY to_number(id);
SELECT * FROM test22  ORDER BY ID+0;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值