Php MYSQL SELECT语句中有关数字和字母的排序问题
我有一个带有列“tag”的表,其中包含数字和字母,例如:Php MYSQL SELECT语句中有关数字和字母的排序问题,php,mysql,select,Php,Mysql,Select,我有一个带有列“tag”的表,其中包含数字和字母,例如: 1 2 3 4a 4b 10 11 12 20 Z1 当我运行以下查询时,我没有得到所需的顺序: SELECT * FROM `items` ORDER BY `tag` ASC; 这将输出为1、11、12、2、20、4a、4b、P1 然后,通过在查询中使用+0或*1,我找到了一个较好的解决方法: SELECT * FROM `items` ORDER BY `tag` + 0 ASC; 这将输出为Z1、1、2、3、4b、4a、10
1
2
3
4a
4b
10
11
12
20
Z1
当我运行以下查询时,我没有得到所需的顺序:
SELECT * FROM `items` ORDER BY `tag` ASC;
这将输出为1、11、12、2、20、4a、4b、P1
然后,通过在查询中使用+0或*1,我找到了一个较好的解决方法:
SELECT * FROM `items` ORDER BY `tag` + 0 ASC;
这将输出为Z1、1、2、3、4b、4a、10、11、12、20,这只是稍微好一点
是否有办法对值进行排序,使其显示为:
1,2,3,4a,4b,10,11,12,20,Z1
我希望避免添加订单列,因为我有30000个项目,而标签只是更大类别的子集。试试这个:
SELECT * FROM `items` ORDER BY CAST(`tag` as UNSIGNED) ASC;
编辑:
似乎要将以数字开头和以字母开头的字符串分开。 如果是这样,请尝试以下方法:
SELECT tag, tag*1,(tag REGEXP '^[0-9]') FROM items
ORDER BY (tag REGEXP '^[0-9]') DESC,
tag*1,tag
更新:这似乎是在MySQL中实现的。即使你真的实现了它,我想它的速度也会非常慢。如果必须按此标记排序,我建议将其拆分为几列,并使用标记列作为这些列的计算连接
标记的格式为:可选字母集、整数、另一个可选字母集。为了正确排序,您需要提取标记的每个部分,这样您就可以将字母作为字符串进行比较,将数字作为整数进行比较
SQLFiddle已关闭,因此下面是该问题的SQLServer解决方案,它可能会帮助您或其他人可视化如何在MySQL中执行此操作,尽管查询将非常不同。在下面的a中是标记
这将为您的数据+一些附加测试数据生成以下内容:
+-----+-------------+--------+-----------+
| a | StartLetter | Number | EndLetter |
+-----+-------------+--------+-----------+
| 1 | | 1 | |
| 2 | | 2 | |
| 3 | | 3 | |
| 4ab | | 4 | ab |
| 4b | | 4 | b |
| 10 | | 10 | |
| 11 | | 11 | |
| 12 | | 12 | |
| 20 | | 20 | |
| B1 | B | 1 | |
| B22 | B | 22 | |
| BA2 | BA | 2 | |
| Z1 | Z | 1 | |
| Z2b | Z | 2 | b |
| Z3 | Z | 3 | |
+-----+-------------+--------+-----------+
尽管如此,考虑到数据排序的复杂性,我认为您首先需要重新考虑按列排序的决定。可能有助于您SQLFiddle出现故障,因此无法转换我的sql server解决方案。。。我认为您需要按以下顺序排序:字符串“0”左侧的字母不存在,左侧或右侧的数字不存在,右侧的字母“0”不存在。但我想你们可能会想重新考虑一下,这是否是一个好的领域。谢谢各位,我已经尝试了我能找到的一切,但都没有得到好的结果。我只是想添加一个订单列,然后用几天的时间手动对数据进行排序。嗨,这会输出Z1、1、2、3、4a、4b、etcHi,这会输出Z1、1、10、11、12、2、20等等。@user1024370我已经更改了查询。现在就试试吧,这很聪明,适用于测试数据。但是,如果希望Z1、Z2和Z10也能自然排序,那么它将失败。
SELECT a
,CASE WHEN a LIKE '[^0-9]%'
THEN LEFT(a, ISNULL(NULLIF(PATINDEX('%[^0-9][0-9]%', a ),0),LEN(a)))
ELSE ''
END AS StartLetter
,CAST(SUBSTRING(a
,PATINDEX('%[0-9]%', a )
,(LEN(a)+2-PATINDEX('%[0-9]%', REVERSE(a)))-PATINDEX('%[0-9]%', a))
AS INT) AS Number
,SUBSTRING(a
,LEN(a)+2-PATINDEX('%[0-9]%', REVERSE(a) )
,LEN(a)-1) AS EndLetter
FROM @t
ORDER BY STartLetter, Number, EndLetter
+-----+-------------+--------+-----------+
| a | StartLetter | Number | EndLetter |
+-----+-------------+--------+-----------+
| 1 | | 1 | |
| 2 | | 2 | |
| 3 | | 3 | |
| 4ab | | 4 | ab |
| 4b | | 4 | b |
| 10 | | 10 | |
| 11 | | 11 | |
| 12 | | 12 | |
| 20 | | 20 | |
| B1 | B | 1 | |
| B22 | B | 22 | |
| BA2 | BA | 2 | |
| Z1 | Z | 1 | |
| Z2b | Z | 2 | b |
| Z3 | Z | 3 | |
+-----+-------------+--------+-----------+