Php 需要按复杂顺序对不规则值进行排序
我正在尝试开发一个系统来显示网页上数据库中的产品。通常这是没有问题的,除了一个制造商有几个不正常的零件号,我需要正确排序 通常情况下,我可以使用一个不可见的列来分类,但这样就很难在两个旧项目之间插入新项目 例如,以下是一些零件号:Php 需要按复杂顺序对不规则值进行排序,php,mysql,Php,Mysql,我正在尝试开发一个系统来显示网页上数据库中的产品。通常这是没有问题的,除了一个制造商有几个不正常的零件号,我需要正确排序 通常情况下,我可以使用一个不可见的列来分类,但这样就很难在两个旧项目之间插入新项目 例如,以下是一些零件号: 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 1
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
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)
我最好的选择是什么?如果他们只是在一个csv文件中制作,然后上传,这不会是一个问题。但由于数据库自动更改,服务器将实时修改值。因此,手动更新它是不可能的。这意味着需要一个后端来插入新的项目,但是通过什么方法可以在另一个项目之间插入项目呢?我不想求助于小数之类的东西来在值之间给我X(比如我有1.00和2.00,我想在它们之间加一个,所以我把它设为1.50)
任何帮助都将不胜感激
编辑:
我想对其进行排序的方式如下:
如果它有连字符,即14-302,则按14排序,然后任何14 xxx按连字符后面的数字排序。
然后,数字将按实际数字排序,802排在45768之前。
然后,后面有字母的任何数字都将按数字排序,字母so 123a位于123b之前,但在122之后。123b在124c之前。
最后,以M-开头的任何内容都将按连字符后的数字排在最后。对于调整后的问题,原则仍然相同。 我的第一反应是使用额外的字段,但可以使用存储函数来处理这些字段。 你仍然需要把你的零件号分成3部分(我认为不超过这个)
- Part1是一个整数,如果存在,则具有第一个数字,否则用maxint填充它(Part1的最大值)
- 第2部分是字符,如果存在,则包含字母
- 第3部分是包含第二个数字(如果存在)的整数
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//
步骤1:定义决定排序的规则。我想我已经做了一些,但我会在编辑中做得更好。在这种情况下,似乎可以使用mysql REGEXP。这是一个供您启动的程序:您可以在此处了解有关用法的更多信息:regexp可能是一个不错的方法,但特定的设置不起作用。将数字分成3个字段是可能的,但会很烦人。为什么我不能使用REGEXP?那要看情况而定。你说它在你的设置中不“正常工作”。你这是什么意思?(排序与您在原始问题中所述完全相同)排序没有按照我在原始问题中所述的方式进行。排序结果是121135723152015 1225等等,这是一点也不正确的。应该是12111252015,350723157。我修改了我的答案。现在每个部分都有一个函数调用。(包括工作)太好了!但复制起来有点复杂,因为我还有一些其他(不太模糊的)数字要排序,比如87-10-2、87-1000等等。REGEXP是另一种选择吗?如果我找不到比这更好的东西,我就用它。