0

我正在尝试开发一个系统来在网页上显示数据库中的产品。通常这没有问题,除了一个制造商有几个异常的零件编号我需要正确排序。

通常,我可以只使用一个不可见的列来整理东西,但这使得在两个旧项目之间插入新项目变得更加困难。

例如,以下是一些零件编号:

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 之前。然后任何后面有字母的数字都将按数字排序,因此 123a 的字母在 123b 之前但在 122 之后。和 123b出现在 124c 之前。最后,以 M- 开头的任何内容都将排在最后,并按连字符后的数字排序。

4

1 回答 1

1

对于您调整后的问题,原则仍然相同。我的第一直觉是使用额外的字段,但您可以使用存储功能。您仍然需要将您的零件号分成 3 部分(我认为它不会超过那个)。

  • Part1 是一个整数,如果存在则具有第一个数字,否则用 maxint 填充它(part1 最大)。
  • Part2 是一个 CHAR 并且包含字母(如果存在)。
  • Part3 是一个 INTEGER,包含第二个数字(如果存在)。

您可以通过为这些值调用函数来进行排序。

这是完整的来源:为方便起见,请提供指向有效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)
于 2013-07-06T21:10:15.833 回答