我有qt_no值,如
AM1,M3,M4,M14,M30,M40,MA01,A10,A13,A07,B01,B10,Z33,Z13等等(实际上是字母后面的任何int 2-3位数字)。
我试过分类
order by length(qt_no), qt_no它达不到我所要求的输出。
我的预期产出是
A01,A07,A10,A13,B01,AM1,M3,M4,M14,M30,M40,MA01,Z13,Z33请记住,这些qt_no值是同一字段和同一表的不同行。
从现在开始我不知道该怎么做。
任何帮助都将不胜感激。
编辑
下面是玩的一个示例数据库。
发布于 2018-10-24 11:54:44
最好的场景是创建两个额外的列,一个用于字母部分,一个用于数字部分;然后它就像ORDER BY alpha_part ASC, num_part ASC一样简单。如果在这两列上有一个联合索引,它也会非常快。
如果您必须在查询时解析该列,则这需要时间--同时也会使索引变得无用,这会使所有的操作都慢得多。但你可以这样做:
...
ORDER BY
REGEXP_REPLACE(qt_no, '\d+', '') ASC,
CAST(REGEXP_REPLACE(qt_no, '\D+', '') AS INTEGER) ASC编辑:我很抱歉,但我不知道如何在5.7上做这件事,除非如下所示:
SELECT qt_no FROM t
ORDER BY
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(qt_no, '0', ''), '1', ''), '2', ''), '3', ''), '4', ''), '5', ''), '6', ''), '7', ''), '8', ''), '9', '') ASC,
CAST(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(qt_no, 'A', ''), 'B', ''), 'C', ''), 'D', ''), 'E', ''), 'F', ''), 'G', ''), 'H', ''), 'I', ''), 'J', ''), 'K', ''), 'L', ''), 'M', ''), 'N', ''), 'O', ''), 'P', ''), 'Q', ''), 'R', ''), 'S', ''), 'T', ''), 'U', ''), 'V', ''), 'W', ''), 'X', ''), 'Y', ''), 'Z', '') AS UNSIGNED) ASC;发布于 2018-10-24 13:22:39
由于在MySQL版本< 8.0中缺少Regex函数,我们可以创建一个自定义函数来从给定字符串中提取数字子字符串。
下面是来自此回答的修改函数,该函数从输入字符串返回整数值。这里所做的修改是返回字符串而不是Int。因为像07这样的数字字符串需要按原样返回,而不是7。
DELIMITER $$
CREATE FUNCTION `ExtractNumber`(in_string VARCHAR(50))
RETURNS VARCHAR(50)
NO SQL
BEGIN
DECLARE ctrNumber VARCHAR(50);
DECLARE finNumber VARCHAR(50) DEFAULT '';
DECLARE sChar VARCHAR(1);
DECLARE inti INTEGER DEFAULT 1;
IF LENGTH(in_string) > 0 THEN
WHILE(inti <= LENGTH(in_string)) DO
SET sChar = SUBSTRING(in_string, inti, 1);
SET ctrNumber = FIND_IN_SET(sChar, '0,1,2,3,4,5,6,7,8,9');
IF ctrNumber > 0 THEN
SET finNumber = CONCAT(finNumber, sChar);
END IF;
SET inti = inti + 1;
END WHILE;
RETURN finNumber;
ELSE
RETURN '';
END IF;
END$$
DELIMITER ;现在,您可以使用这个自定义函数,并按字母部分进行排序,然后按数字部分(强制转换为unsigned)排序。
SELECT id,
name,
REPLACE(name, ExtractNumber(name), '') as strpart,
CAST(ExtractNumber(name) AS UNSIGNED) as numpart
FROM test
ORDER BY strpart,
numpart发布于 2018-10-24 12:34:36
不漂亮,正如我们已经说过的,因为我们是字符串解析,它将是缓慢的。这假设您的格式是Alpha,那么数值永远不会混合。它查找第一个数值,然后根据该发现将其拆分为两列。
我只是想通过qt_no+0进行排序,以获得自然的排序,但这是行不通的。所以我走了另一条路..。
Field1是你的qt_no字段..。
SELECT Field1,
#Use this to just get the number values but since we lose trailing zeros...Step 2 we reverse the value so numbers are first allowing the convert to drop the letters. unfortunately this also drops the trailing (leading since we reversed) zeros.
@NumStep1 := reverse(CONVERT(reverse(Field1), SIGNED)) NumStep1,
#We got the postiion of the first number... so get the whole number now.
@NumStep2 :=substring(Field1,locate(@numStep1,Field1),length(Field1)) NumStep2,
@Alpha:= substring(Field1,1,Locate(@numStep2,Field1)-1) Alpha
FROM (
SELECT 'AM1' as Field1 UNION ALL
SELECT 'M3' as Field1 UNION ALL
SELECT 'M4' as Field1 UNION ALL
SELECT 'M14' as Field1 UNION ALL
SELECT 'M30' as Field1 UNION ALL
SELECT 'M40' as Field1 UNION ALL
SELECT 'MA01' as Field1 UNION ALL
SELECT 'A10' as Field1 UNION ALL
SELECT 'A13' as Field1 UNION ALL
SELECT 'A07' as Field1 UNION ALL
SELECT 'B01' as Field1 UNION ALL
SELECT 'B10' as Field1 UNION ALL
SELECT 'Z33' as Field1 UNION ALL
SELECT 'Z13' as Field1) Z
ORDER BY Alpha, NumStep2*1给我们:
+----+--------+----------+----------+-------+
| | Field1 | NumStep1 | NumStep2 | Alpha |
+----+--------+----------+----------+-------+
| 1 | A10 | 1 | 10 | A |
| 2 | A13 | 13 | 13 | A |
| 3 | A07 | 07 | 07 | A |
| 4 | AM1 | 1 | 1 | AM |
| 5 | B10 | 1 | 10 | B |
| 6 | B01 | 01 | 01 | B |
| 7 | M3 | 3 | 3 | M |
| 8 | M4 | 4 | 4 | M |
| 9 | M14 | 14 | 14 | M |
| 10 | M30 | 3 | 30 | M |
| 11 | M40 | 4 | 40 | M |
| 12 | MA01 | 01 | 01 | MA |
| 13 | Z33 | 33 | 33 | Z |
| 14 | Z13 | 13 | 13 | Z |
+----+--------+----------+----------+-------+没有用户变量,而是将数据拆分为alpha &数值。
SELECT Field1,
substring(Field1,locate(reverse(CONVERT(reverse(Field1), SIGNED)),Field1),length(Field1)) NumStep2,
substring(Field1,1,Locate(substring(Field1,locate(reverse(CONVERT(reverse(Field1), SIGNED)),Field1),length(Field1)),Field1)-1) Alpha
FROM (
SELECT 'AM1' as Field1 UNION ALL
SELECT 'M3' as Field1 UNION ALL
SELECT 'M4' as Field1 UNION ALL
SELECT 'M14' as Field1 UNION ALL
SELECT 'M30' as Field1 UNION ALL
SELECT 'M40' as Field1 UNION ALL
SELECT 'MA01' as Field1 UNION ALL
SELECT 'A10' as Field1 UNION ALL
SELECT 'A13' as Field1 UNION ALL
SELECT 'A07' as Field1 UNION ALL
SELECT 'B01' as Field1 UNION ALL
SELECT 'B10' as Field1 UNION ALL
SELECT 'Z33' as Field1 UNION ALL
SELECT 'Z13' as Field1) Z
ORDER BY Alpha, NumStep2*1https://stackoverflow.com/questions/52968151
复制相似问题