MySQL排序表合并字段上具有相同值的行,但保持相互顺序

时间:2019-06-06 08:12:58

标签: mysql sql-order-by

我有一个要根据字母数字字段(在某些情况下可以重叠)排序的MySQL表。我尝试了几次查询,但我总是很接近,但没有达到目标。

我的桌子是:

TABLE
Sizes
COLUMN
ScaleCode   varchar(6)
SizeIndex   smallint(6) 
SizeName    varchar(30)
PRIMARY KEY
ScaleCode, SizeIndex

数据:

+-----------+-----------+----------+
| ScaleCode | SizeIndex | SizeName |
+-----------+-----------+----------+
| 00001     | 1         | 13       |
| 00001     | 2         | 14       |
| 00001     | 3         | 15       |
| 00002     | 1         | 14       |
| 00002     | 2         | 15       |
| 00002     | 3         | 16       |
| 00002     | 4         | 17       |
| 00002     | 5         | 18       |
| 00002     | 6         | 19       |
| 00002     | 7         | 20       |
| 00003     | 1         | 18       |
| 00003     | 2         | 19       |
| 00003     | 3         | 20       |
| 00003     | 4         | 21       |
| 00003     | 5         | 22       |
| 00004     | 1         | ONE_SIZE |
| 00005     | 1         | 2S       |
| 00005     | 2         | S        |
| 00005     | 3         | M        |
| 00005     | 4         | L        |
| 00005     | 5         | 2L       |
+-----------+-----------+----------+

我的目标是对SizeName执行选择,结果如下:

+----------+
| SizeName |
+----------+
| ONE_SIZE |
| 2S       |
| S        |
| M        |
| L        |
| 2L       |
| 13       |
| 14       |
| 15       |
| 16       |
| 17       |
| 18       |
| 19       |
| 20       |
| 21       |
| 22       |
+----------+

因此,我只需要显示一次重叠的SizeName值,例如14和15都可以在ScaleCode 00001和000002中使用,或者18,19,20都可以在ScaleCode 00002和00003中使用。 棘手的事情是SizeName值是字母数字,因此我需要在相同的比例尺代码内保持相互的顺序,即'2S'和'2L'必须与其他尺寸的比例尺具有相同的顺序,而不是按数字排序。

我尝试过的是:

SELECT DISTINCT SizeName  
FROM Sizes 
ORDER BY SizeName, ScaleCode, SizeIndex

但是:

+----------+
| SizeName |
+----------+
| 2L       |
| 2S       |
| 13       |
| 14       |
| 15       |
| 16       |
| 17       |
| 18       |
| 19       |
| 20       |
| 21       |
| 22       |
| L        |
| M        |
| ONE_SIZE |
| S        |
+----------+

这不是我期望的,因为不维护ScaleCode 00005内的顺序。 所以,我尝试了:

SELECT DISTINCT SizeName  
FROM Sizes 
ORDER BY SizeName + 0, ScaleCode, SizeIndex

但是:

+----------+
| SizeName |
+----------+
| S        |
| M        |
| L        |
| ONE_SIZE |
| 2L       |
| 2S       |
| 13       |
| 14       |
| 15       |
| 16       |
| 17       |
| 18       |
| 19       |
| 20       |
| 21       |
| 22       |
+----------+

如果仅不能将'2L'和'2S'视为数字,那会很好。

更新: ONE_SIZE可以无处不在,但不能在其他刻度范围内。 因此,它可以在标度“ 2S,S,M,L,2L”之前或之后,但不能在两者之间。 我需要保持规模一致。

在此先感谢所有想帮助我的人。

2 个答案:

答案 0 :(得分:0)

也许有些复杂,但是我提出了这个解决方案:

SELECT sz.SizeName FROM
(SELECT DISTINCT IF(
  (SELECT COUNT(p1.SizeName)
   FROM Sizes p1
   WHERE p1.SizeName NOT REGEXP '^[0-9]+[\\.\\,]?[0-9]*$' AND p1.SizeName = pt.SizeName) >
  (SELECT COUNT(p2.SizeName)
   FROM Sizes p2
   WHERE p2.SizeName REGEXP '^[0-9]+[\\.\\,]?[0-9]*$' AND p2.SizeName = pt.SizeName),
   CONCAT('text', pt.SizeName), pt.SizeName) AS sortable, pt.SizeName 
FROM Sizes pt) AS sz

结果:

+----------+
| SizeName |
+----------+
| 13       |
| 14       |
| 15       |
| 16       |
| 17       |
| 18       |
| 19       |
| 20       |
| 21       |
| 22       |
| ONE_SIZE |
| 2S       |
| S        |
| M        |
| L        |
| 2L       |
+----------|

通过这种方式,我可以保持相互的顺序并合并重叠的尺寸。 我知道它不是那么优雅,这是我所不知道的最佳解决方案。 欢迎发表评论或其他答案。

答案 1 :(得分:0)

首先,您需要在“ ScaleCode”和“ ScaleIndex”周围使用“ MIN()”进行“按SizeName分组”。之后,您可以正确订购