在cast()时按顺序按大小写mysql

在cast()时按顺序按大小写mysql,mysql,Mysql,我需要对ID字段进行排序,但是ID字段是动态的,我需要在排序之前进行判断,如果它是一个纯数字,那么我将它转换为数字类型,然后进行排序。但是我在cast()时遇到了一些问题,有人能帮我吗 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for BASIS_EXP_ORG -- ---------------------------- DROP TAB

我需要对ID字段进行排序,但是ID字段是动态的,我需要在排序之前进行判断,如果它是一个纯数字,那么我将它转换为数字类型,然后进行排序。但是我在cast()时遇到了一些问题,有人能帮我吗

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for BASIS_EXP_ORG
-- ----------------------------
DROP TABLE IF EXISTS `BASIS_EXP_ORG`;
CREATE TABLE `BASIS_EXP_ORG`  (
  `NAME` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'name',
  `ORG_ID` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'org',
  PRIMARY KEY (`ORG_ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of BASIS_EXP_ORG
-- ----------------------------
INSERT INTO `BASIS_EXP_ORG` VALUES ('OU_2', '101');
INSERT INTO `BASIS_EXP_ORG` VALUES ('INV_2', '141');
INSERT INTO `BASIS_EXP_ORG` VALUES ('OU_1', '85');

SET FOREIGN_KEY_CHECKS = 1;

这是你想要的吗? 我认为您只需要将(ORG_ID+0)放置在order by phase,将其转换为数字类型。 请试试这个

选择不同的组织ID,
名称为文本
来自BASIS\U EXP\U ORG
其中1=1
以及(101141,85)中的组织ID
订货人(组织标识+0)说明

如果您使用的是MySQL版本8+和MariaDB 10+,您可以使用
REGEXP\u REPLACE
删除字符串,然后
CAST
it:

 SELECT   DISTINCT ORG_ID AS id,CAST(REGEXP_REPLACE(ORG_ID,'[a-zA-Z]','') AS SIGNED),
          NAME AS  TEXT         
 FROM     BASIS_EXP_ORG
 WHERE    1 = 1
 ORDER BY CAST(REGEXP_REPLACE(ORG_ID,'[a-zA-Z]','') AS SIGNED) ASC;
请点击此处查看演示:

为了测试,我在fiddle中添加了一些行数据,并删除了(101141,85)中的
和ORG\u ID

编辑: 下面的查询应该能够在较旧的MySQL上运行:

 SELECT DISTINCT ORG_ID AS id,SUBSTRING(ORG_ID,
        LEAST(
        IF(LOCATE(1,org_id)=0,99,LOCATE(1,org_id)),
        IF(LOCATE(2,org_id)=0,99,LOCATE(2,org_id)),
        IF(LOCATE(3,org_id)=0,99,LOCATE(3,org_id)),
        IF(LOCATE(4,org_id)=0,99,LOCATE(4,org_id)),
        IF(LOCATE(5,org_id)=0,99,LOCATE(5,org_id)),
        IF(LOCATE(6,org_id)=0,99,LOCATE(6,org_id)),
        IF(LOCATE(7,org_id)=0,99,LOCATE(7,org_id)),
        IF(LOCATE(8,org_id)=0,99,LOCATE(8,org_id)),
        IF(LOCATE(9,org_id)=0,99,LOCATE(9,org_id))),99)+0 AS num,
          NAME AS TEXT         
 FROM     BASIS_EXP_ORG
 WHERE    1  = 1
 ORDER BY num ASC;
MySQL 5.7上的演示:

如您所见,我正在使用一系列函数从原始数据中删除字符串。首先,我使用
LOCATE
查找1-9之间的数字及其位置。以下查询和结果有助于进一步澄清:

 SELECT *,
        LOCATE(1,org_id),
        LOCATE(2,org_id),
        LOCATE(3,org_id),
        LOCATE(4,org_id),
        LOCATE(5,org_id),
        LOCATE(6,org_id),
        LOCATE(7,org_id),
        LOCATE(8,org_id),
        LOCATE(9,org_id) FROM BASIS_EXP_ORG;

+-------+----------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
| NAME  |  ORG_ID  |   LOCATE   |   LOCATE   |   LOCATE   |   LOCATE   |   LOCATE   |   LOCATE   |   LOCATE   |   LOCATE   |   LOCATE   |
|       |          | (1,org_id) | (2,org_id) | (3,org_id) | (4,org_id) | (5,org_id) | (6,org_id) | (7,org_id) | (8,org_id) | (9,org_id) |
+-------+----------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
| OU_1  | 00000001 | 8          | 0          | 0          | 0          | 0          | 0          | 0          | 0          | 0          |
| OU_2  | 101      | 1          | 0          | 0          | 0          | 0          | 0          | 0          | 0          | 0          |
| INV_2 | 141      | 1          | 0          | 0          | 2          | 0          | 0          | 0          | 0          | 0          |
| OU_3  | 81       | 2          | 0          | 0          | 0          | 0          | 0          | 0          | 1          | 0          |
| OU_1  | 85       | 0          | 0          | 0          | 0          | 2          | 0          | 0          | 1          | 0          |
| INV_2 | a101     | 2          | 0          | 0          | 0          | 0          | 0          | 0          | 0          | 0          |
| OU_1  | b40      | 0          | 0          | 0          | 2          | 0          | 0          | 0          | 0          | 0          |
| OU_1  | c0001    | 5          | 0          | 0          | 0          | 0          | 0          | 0          | 0          | 0          |
| OU_2  | c101     | 2          | 0          | 0          | 0          | 0          | 0          | 0          | 0          | 0          |
+-------+----------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
这背后的逻辑是知道
LOCATE
(如果有)中所述号码的位置在哪里。然后,如果它返回
0
(表示该数字不存在),则给它
99
,这样当
最小值出现时,它不会看到零。但是,使用
LEAST
的主要原因是要获得找到的第一个数字,而不是找到的最小数字。也就是说,请参考上面的示例,查找
ORG\u ID=81
的数据
(LOCATE(1,org\u id)
在位置2中找到了数字1,而
(LOCATE(8,org\u id)
在位置1找到了数字8。如果我们采用最小的数字进行判断,那么在
子字符串
函数中我们将得到数字1而不是81(这花了我一段时间才弄清楚;P)。然后我们在
子字符串中使用它们,并在最后检索到的值处添加
+0

tl;dr>如果我们将其转换为普通查询,基本上会得到如下结果:

SELECT   DISTINCT ORG_ID AS id, SUBSTRING(ORG_ID,**8**,99)+0 as num
FROM     BASIS_EXP_ORG
WHERE    1  = 1
AND      ORG_ID='00000001'
ORDER BY num ASC;

获取
**8**
是所有过程发生的地方。

“我有一些问题”-请使用标签下方的
edit
按钮编辑您的问题,并描述您遇到的问题。谢谢。如果不是数字或非数字字符与数字字符的组合,该怎么办?如何排序?您的MySQL版本是什么?不,因为组织ID是动态的,它可能是字符串+数字的形式,例如作为c001,或者它可能是一个纯数字,比如101,所以我需要在排序之前对它进行判断。是的,dik11,我刚刚测试过,上面的查询似乎适用于您的两种情况。哦,糟糕。实现这一点会很棘手。我会试试something@dik11,请检查我的最新答案是否适用于您的情况。谢谢
SELECT   DISTINCT ORG_ID AS id, SUBSTRING(ORG_ID,**8**,99)+0 as num
FROM     BASIS_EXP_ORG
WHERE    1  = 1
AND      ORG_ID='00000001'
ORDER BY num ASC;