MySQL按同一列中的混合ASC/DESC排序

MySQL按同一列中的混合ASC/DESC排序,mysql,sql,sql-order-by,Mysql,Sql,Sql Order By,我试图在同一列中按ASC和DESC order对数据库中的产品箱位置进行排序,以允许仓库拣选员在仓库岛中穿行拣选产品。换句话说,当分拣员从仓库收到一批要分拣的订单时,系统需要在1号岛的前端启动它们,然后订单分拣沿着1号岛一直到最后。然后它会让他们跳到2号岛的尽头(而不是起点),然后他们会朝2号岛的前面走,然后从3号岛的前面开始,依此类推 箱子位置的格式为:ISLE-BAY-SHELF-SLOT/bin 以下是要拾取的箱子位置的示例数据表: 1-0-A-01 1-1-D-06 1-2-E-10

我试图在同一列中按ASC和DESC order对数据库中的产品箱位置进行排序,以允许仓库拣选员在仓库岛中穿行拣选产品。换句话说,当分拣员从仓库收到一批要分拣的订单时,系统需要在1号岛的前端启动它们,然后订单分拣沿着1号岛一直到最后。然后它会让他们跳到2号岛的尽头(而不是起点),然后他们会朝2号岛的前面走,然后从3号岛的前面开始,依此类推

箱子位置的格式为:ISLE-BAY-SHELF-SLOT/bin 以下是要拾取的箱子位置的示例数据表:

  • 1-0-A-01
  • 1-1-D-06
  • 1-2-E-10
  • 1-2-E-11
  • 1-10-A-01
  • 2-1-D-02
  • 2-1-C-12
  • 2-5-F-01
  • 3-5-A-12
  • 3-6-D-01
  • 4-5-A-02
  • 4-5-A-03
  • 4-5-B-10
我需要执行SQL查询并提取位置并按如下方式排序:

  • 1-0-A-01
  • 1-1-D-06
  • 1-2-E-10
  • 1-2-E-11
  • 1-10-A-01
  • 2-5-F-01
  • 2-1-D-02
  • 2-1-C-12
  • 3-5-A-12
  • 3-6-D-01
  • 4-5-B-10
  • 4-5-A-03
  • 4-5-A-02

仅使用SQL查询就可以做到这一点吗?

是的,这可以在SQL查询中完成,尽管语法非常简单

首先需要表达式将ISLE-BAY-SHELF“拆分”为单独的组件,然后在ORDER BY子句中使用这些表达式

对于MySQL

将一些示例表达式放入“选择”列表,以便查看它们返回的内容:

SELECT SUBSTRING_INDEX('1-10-A-01','-',1)+0 AS ISLE
     , SUBSTRING_INDEX(SUBSTRING_INDEX('1-10-A-01','-',2),'-',-1)+0 AS BAY
     , SUBSTRING_INDEX(SUBSTRING_INDEX('1-10-A-01','-',3),'-',-1) AS SHELF
     , SUBSTRING_INDEX('1-10-A-01','-',-1)+0 AS `SLOT/BIN`
这些表达式基于这样的假设,即始终有三个破折号,并且始终采用数值格式

给定示例数据,我们可以检查ISLE组件是偶数还是奇数,然后根据该数据对间隔进行升序或降序。但这可能不是你想要的,如果跳过了一个通道,如果我们完全跳过了第2通道,只跳过了第1和第3通道

CREATE TABLE ibss (ibss VARCHAR(20));
INSERT INTO ibss (ibss) VALUES 
('1-0-A-01')
,('1-1-D-06')
,('1-2-E-10')
,('1-2-E-11')
,('1-10-A-01')
,('2-5-F-01')
,('2-1-D-02')
,('2-1-C-12')
,('3-5-A-12')
,('3-6-D-01')
,('4-5-B-10')
,('4-5-A-03')
,('4-5-A-02');


SELECT i.ibss
     , SUBSTRING_INDEX(i.ibss,'-',1)+0 AS ISLE
     , SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0 AS BAY
     , SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',3),'-',-1) AS SHELF
     , SUBSTRING_INDEX(i.ibss,'-',-1)+0 AS `SLOT/BIN`
     , (SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2 AS odd_or_even_isle
     , IF((SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2
         ,SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0,NULL
       ) AS odd_bay
     , IF((SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2
         ,NULL,SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0
       ) AS even_bay
  FROM ibss i
 ORDER BY -- ascending by ISLE
         SUBSTRING_INDEX(i.ibss,'-',1)+0 ASC
         -- ascending by BAY if ISLE is odd
       , IF((SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2
           ,SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0,NULL
         ) ASC
         -- descending by BAY if ISLE is even
       , IF((SUBSTRING_INDEX(i.ibss,'-',1)+0) MOD 2
           ,NULL,SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',2),'-',-1)+0
         ) DESC
         -- ascending by shelf
       , SUBSTRING_INDEX(SUBSTRING_INDEX(i.ibss,'-',3),'-',-1)
         -- ascending by SLOT/BIN
       , SUBSTRING_INDEX(i.ibss,'-',-1)+0
同样,按间隔排列的上升/下降顺序将取决于岛是偶数还是奇数,而不是取决于这是一个交替的通道。(如果你想让拣选者沿着同一个方向沿着过道向下移动,而不是朝相反的方向移动,那么这种行为可能是可取的。)要根据“过道更改”更改订单,我们需要添加一些额外的逻辑

    ibss         ISLE     BAY  SHELF   SLOT/BIN  odd_or_even_isle  odd_bay  even_bay  
    ---------  ------  ------  ------  --------  ---------------- -------  ----------
    1-0-A-01        1       0  A              1                1        0      (NULL)
    1-1-D-06        1       1  D              6                1        1      (NULL)
    1-2-E-10        1       2  E             10                1        2      (NULL)
    1-2-E-11        1       2  E             11                1        2      (NULL)
    1-10-A-01       1      10  A              1                1       10      (NULL)
    2-5-F-01        2       5  F              1                0   (NULL)           5
    2-1-C-12        2       1  C             12                0   (NULL)           1
    2-1-D-02        2       1  D              2                0   (NULL)           1
    3-5-A-12        3       5  A             12                1        5      (NULL)
    3-6-D-01        3       6  D              1                1        6      (NULL)
    4-5-A-02        4       5  A              2                0   (NULL)           5
    4-5-A-03        4       5  A              3                0   (NULL)           5
    4-5-B-10        4       5  B             10                0   (NULL)           5

首先,您应该正确地将这些数据元素拆分到表中它们自己的列中。完成此操作后,此问题变得微不足道,您甚至可以按书架/箱子进行排序:

SELECT isle,
    (IF(MOD(isle/2)=1,1,-1) * bay) AS baysort,
    bay,
    shelf,
    bin
FROM table
ORDER BY
    isle ASC,
    baysort ASC,
    shelf ASC,
    bin ASC
注意,这里我将计算
baysort
列,这基本上使
bay
成为偶数岛的负值


显然,您可以在应用程序中放弃baysort值(或者简单地将其移动到排序条件,而不是select-我在这里使用select,以便您可以直观地看到发生了什么)。

如果这些坐标是text/varchar字段中的字符串,则不,您无法运行简单的查询对其进行正确排序。您需要规范化DB,使每个坐标分量都位于其自己的字段中,然后一个简单的
按岛、湾、架、槽的顺序将执行您想要的操作。您可以尝试按它们各自的部分进行排序:
按子字符串索引排序(子字符串索引(您的列“-”,1),“,-1),”子字符串索引(子字符串索引(您的列“-”,2),“”,-1),…
等。但这可能是因为slowIt是一个varchar字段。您在这里提出了一个很好的观点。我们确实需要将这些数据标准化。这将使事情在未来变得容易得多。谢谢,很好用。我们确实需要在数据库中将这些位置拆分为单独的列,但在那之前,这似乎是可行的。非常感谢。