MySQL命令由同一列中的混合ASC / DESC组成

时间:2014-06-20 19:08:15

标签: mysql sql sql-order-by

我正在尝试通过同一列中的ASC和DESC订单从数据库中对产品仓位置进行排序,以允许仓库选择器编织仓库岛以挑选产品。换句话说,当一个拣货员获得一批从仓库中拣选的订单时,系统需要在岛1的前面启动它们,然后将拣货从码头下到最后。然后它会将它们跳到岛2的末端(而不是开始),然后它们会朝着岛2的前方行进,然后从岛3的前面开始,依此类推。

bin位置的格式为:ISLE - BAY - SHELF - SLOT / BIN 以下是要选择的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查询执行此操作?

2 个答案:

答案 0 :(得分:1)

是的,这可以在SQL查询中完成,但语法并不重要。

你首先需要表达式来分析"分裂"将ISLE-BAY-SHELF分成单独的组件,然后在ORDER BY子句中使用这些表达式。

MySQL

一些示例表达式,放入SELECT列表中,以便我们可以看到它们返回的内容:

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组件是偶数还是奇数,然后根据它来命令BAY上升或下降。但是,如果我们跳过一个过道,如果我们完全跳过过道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

同样,BAY的上升/下降顺序将取决于ISLE是偶数还是奇数,而不是这是否是交替过道。 (如果您希望拣货员沿过道向同一方向移动,而不是朝相反方向移动,则可能需要此行为。)为了根据"过道更改"更改订单,我们就可以了需要添加一些额外的逻辑。

    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

答案 1 :(得分:0)

首先,您应该正确地将这些数据元素拆分到表中的各自列中。完成后,这个问题变得微不足道,甚至允许您按shelf / bin排序:

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,这样您就可以直观地看到发生了什么)。

相关问题