MySQL按同一列中的混合ASC/DESC排序
我试图在同一列中按ASC和DESC order对数据库中的产品箱位置进行排序,以允许仓库拣选员在仓库岛中穿行拣选产品。换句话说,当分拣员从仓库收到一批要分拣的订单时,系统需要在1号岛的前端启动它们,然后订单分拣沿着1号岛一直到最后。然后它会让他们跳到2号岛的尽头(而不是起点),然后他们会朝2号岛的前面走,然后从3号岛的前面开始,依此类推 箱子位置的格式为:ISLE-BAY-SHELF-SLOT/bin 以下是要拾取的箱子位置的示例数据表: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
- 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
- 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字段。您在这里提出了一个很好的观点。我们确实需要将这些数据标准化。这将使事情在未来变得容易得多。谢谢,很好用。我们确实需要在数据库中将这些位置拆分为单独的列,但在那之前,这似乎是可行的。非常感谢。