我正在尝试开发一个系统来显示网页上数据库中的产品。通常这没有问题,除了一个制造商有几个我需要正确排序的异常部件号。
通常情况下,我可以使用不可见的列对事物进行排序,但这会使得在两个旧项目之间插入新项目变得更加困难。
例如,以下是部分编号:
1211
1225
14-302
14-303
2015
23157
3507
35280UP
42-3309
42-3312
4241
现在,mfgr的正常顺序产生上述顺序。 它应该是更像这样的东西:
14-302
14-303
42-3309
42-3312
1211
1225
2015
3507
4241
23157
35280UP
在正确排序时,最好的选择是什么?如果它们只是在csv文件中制作并在之后上传,那么这将不是问题。但由于数据库自动更改,服务器将实时修改值。因此,手动更新它是不可能的。这意味着将需要后端插入新项目,但是我可以通过什么方法在另一个项目之间插入项目?我宁愿不使用像小数这样的东西给我两个值之间的X(就像我有1.00和2.00而我想把它们放在它们之间,所以我把它设为1.50)。
任何帮助都将不胜感激。
修改
我想对它进行排序的方式是这样的: 如果它有一个连字符,即14-302,它按14排序,然后任何14-xxx按连字符后面的数字排序。 然后,只是数字将按实际数字排序,802在45768之前。 然后任何带有字母的数字将按数字排序,字母123b在123b之前但在122之后.123b在124c之前。 最后,任何以M-开头的东西都会被排序,最后是连字符。
答案 0 :(得分:1)
根据调整后的问题,原则仍然相同。 我的第一直觉是使用额外的字段但你可以使用存储的函数。 你仍然需要将你的部分编号分成3部分(我认为它不超过那部分)。
您可以通过调用这些值的函数进行排序。
以下是完整的来源:
为方便起见,指向工作SQL Fiddle的链接。
它真的是草率/快速编程,但它的工作原理。在很短的时间内放在一起,我确信有一点需要改进。你可以自己调整一下。稍后您可以从视图中删除part1,part2和part3。 (但保留在order by
)这只是为了说明排序是如何完成的。
DROP PROCEDURE IF EXISTS `uGetParts`//
DROP FUNCTION IF EXISTS `uExtractPart1`//
DROP FUNCTION IF EXISTS `uExtractPart2`//
DROP FUNCTION IF EXISTS `uExtractPart3`//
CREATE PROCEDURE `uGetParts`(
IN ins varchar(50),
OUT num1 int unsigned,
OUT num2 int unsigned,
OUT num3 int unsigned)
NO SQL
BEGIN
SET num1=0;
SET num2=0;
SET num3=0;
WHILE (num1<length(ins)) AND
(SUBSTRING(ins,num1+1,1) REGEXP('(^[0-9]+$)')=1) DO
SET num1=num1+1;
END WHILE;
SET num2=num1;
WHILE (num2<length(ins)) AND
(SUBSTRING(ins,num2+1,1) REGEXP('(^[0-9]+$)')=0) DO
SET num2=num2+1;
END WHILE;
SET num3=num2;
WHILE (num3<length(ins)) AND
(SUBSTRING(ins,num3+1,1) REGEXP('(^[0-9]+$)')=1) DO
SET num3=num3+1;
END WHILE;
END//
CREATE FUNCTION `uExtractPart1`(ins varchar(50))
RETURNS int unsigned NO SQL
BEGIN
DECLARE num1 INT default 0;
DECLARE num2 INT default 0;
DECLARE num3 INT default 0;
call uGetParts(ins,num1,num2,num3);
IF num1>0 THEN
RETURN CAST(SUBSTRING(ins,1,num1) AS UNSIGNED);
ELSE
RETURN ~0 >> 32;
END IF;
END//
CREATE FUNCTION `uExtractPart2`(ins varchar(50))
RETURNS varchar(50) NO SQL
BEGIN
DECLARE num1 INT default 0;
DECLARE num2 INT default 0;
DECLARE num3 INT default 0;
call uGetParts(ins,num1,num2,num3);
IF num2>num1 THEN
RETURN SUBSTRING(ins,num1+1,num2-num1);
ELSE
RETURN '';
END IF;
END//
CREATE FUNCTION `uExtractPart3`(ins varchar(50))
RETURNS int unsigned NO SQL
BEGIN
DECLARE num1 INT default 0;
DECLARE num2 INT default 0;
DECLARE num3 INT default 0;
call uGetParts(ins,num1,num2,num3);
IF num3>num2 THEN
RETURN CAST(SUBSTRING(ins,num2+1,num3-num2) AS UNSIGNED);
ELSE
RETURN 0;
END IF;
END//
您可以这样称呼它:
SELECT
id,
TYPE,
uExtractPart1(TYPE) as part1,
uExtractPart2(TYPE) as part2,
uExtractPart3(TYPE) as part3
FROM Article
ORDER BY
uExtractPart1(TYPE),
uExtractPart2(TYPE),
uExtractPart3(TYPE)