私の考えは、列を固定長の文字列に変換し、英数字と数字をブロックに並べることです。
Input string | aligned string
---------------------------------------------------------------------------------------
Mova 16 | MOVA......0000000016
Mova 110 | MOVA......0000000110
Mova 180 | MOVA......0000000180
Mova 160N | MOVA......0000000160N.........
"GIACOMINI" R780 DN15 v/2 kampinis | GIACOMINI.R.........0000000780DN........000..etc.
"GIACOMINI" R780 DN20 v/3 kampinis | GIACOMINI.R.........0000000780DN........000..etc.
次に、整列された文字列を使用して行を並べ替えることができますが、結果を取得するには、カスタム関数を作成する必要があります。
DROP FUNCTION IF EXISTS strformat;
SET GLOBAL log_bin_trust_function_creators=TRUE;
DELIMITER |
CREATE FUNCTION strformat(str VARCHAR(128))
RETURNS VARCHAR(128)
BEGIN
DECLARE i INT;
DECLARE last INT;
DECLARE curr INT;
DECLARE res VARCHAR(128);
DECLARE block VARCHAR(10);
SET res='';
SET block='';
SET i=1;
IF LENGTH(str) = 0 THEN
RETURN NULL;
END IF;
WHILE i <= LENGTH(str) DO
SET curr=IF(MID(str, i, 1) RLIKE '[A-Z,a-z]', 1,
IF(MID(str, i, 1) RLIKE '[0-9]', 2, 0));
IF (block='') OR (last=curr) THEN
SET block = CONCAT(block,
IF((curr=1) OR (curr=2), MID(str, i, 1), ''));
ELSE
IF last=2 THEN
SET res = CONCAT(res,
REPEAT('0', 10 - LENGTH(block)), block);
ELSE
SET res = CONCAT(res,
block, REPEAT(' ', 10 - LENGTH(block)));
END IF;
SET block = IF((curr=1) OR (curr=2), MID(str, i, 1), '');
END IF;
SET last=curr;
SET i = i + 1;
END WHILE;
IF curr=1 THEN
SET res = CONCAT(res, block, REPEAT(' ', 10 - LENGTH(block)));
ELSEIF curr=2 THEN
SET res = CONCAT(res, REPEAT('0', 10 - LENGTH(block)), block);
END IF;
RETURN UCASE(res);
END;
|
DELIMITER ;
(ここでは、各ブロックを 10 文字に制限する必要があります)。
その後、次の順序で注文できます。
ORDER BY strformat(`my_value`)