varchar类型

时间:2017-03-22 09:22:29

标签: mysql sql sql-order-by

我有以下列 strand ,它按升序排序,但在3.1之后取3.10而不是3.2 ..

列是varchar类型..

 Strand
 3.1
 3.1.1
 3.1.1.1
 3.1.1.2
 3.1.2
 3.1.2.1
 3.10       # wrong  
 3.10.1     # wrong
 3.10.1.1   # wrong
 3.2        <- this should have been after 3.1.2.1
 3.2.1
 3.2.1.1
 ..
 3.9
 3.9.1.1
         <- here is where 3.10 , 3.10.1 and 3.10.1.1 should reside

我使用以下查询对其进行排序;

SELECT * FROM [table1]
ORDER BY RPAD(Strand,4,'.0') ;

如何确保以正确的方式排序,以便3.10,3.10.1和3.10.1.1终于

5 个答案:

答案 0 :(得分:0)

您可以在字段的整数值上排序结果baset。你的代码看起来像

select [myfield]from [mytable] order by 
convert(RPAD(replace([myfield],'.',''),4,0),UNSIGNED INTEGER);

在此代码中,替换功能将清除点(。)
希望瘦弱的帮助

答案 1 :(得分:0)

您必须将每组数字标准化

SELECT * FROM [table1]
ORDER BY CONCAT(
    LPAD(SUBSTRING_INDEX(Strand,'.',1),3,'0'), '-',
    LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX(Strand,'.',2),'.',-1),3,'0'), '-',
    LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX(Strand,'.',3),'.',-1),3,'0'), '-',
    LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX(Strand,'.',3),'.',-1),3,'0'));

<强>样品

mysql> SELECT CONCAT(
    ->     LPAD(SUBSTRING_INDEX('3.10.1.1','.',1),3,'0'), '-',
    ->     LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX('3.10.1.1','.',2),'.',-1),3,'0'), '-',
    ->     LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX('3.10.1.1','.',3),'.',-1),3,'0'), '-',
    ->     LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX('3.10.1.1','.',3),'.',-1),3,'0'));
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| CONCAT(
    LPAD(SUBSTRING_INDEX('3.10.1.1','.',1),3,'0'), '-',
    LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX('3.10.1.1','.',2),'.',-1),3,'0'), '-',
    LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX('3.10.1.1','.',3),'.',-1),3,'0'), '-',
    LPAD(SUBSTRING_INDEX(SUBSTRI |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 003-010-001-001                                                                                                                                                                                                                                                  |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0,00 sec)

答案 2 :(得分:0)

如果您的数据中的点(.)不超过3,您可以尝试:

select *
from demo
order by replace(Strand, '.', '') * pow(10, (3 + length(replace(Strand, '.', '')) - length(Strand)))

如果该点不确定,那么您可以使用子查询来获得最大点数:

select demo.Strand
from demo
cross join (
    select max(length(Strand) - length(replace(Strand, '.', ''))) as num from demo
) t
order by replace(Strand, '.', '') * pow(10, (num + length(replace(Strand, '.', '')) - length(Strand)))

请参阅Rextester中的demo

如您所见,我在order by子句中使用了函数replacelengthpow

1)replace(Strand, '.', '')会给我们int数字,如:
    replace('3.10.1.1', '.', '') =&gt; 31011;
2)(3 + length(replace(Strand, '.', '')) - length(Strand))将给出我们在Strand中最大点数减去点数的点数,如:
3.1 =&gt; 2;
3)pow返回X的值,增加到Y的幂;

因此样本数据的计算方式如下:

3100
3110
3111
3112
3120
3121
31000
31010
31011
3200
3210
3211
3900
3911

通过这些词汇,您将获得正确的排序。

答案 3 :(得分:0)

原因“strand”列是文本数据,因此将按字母顺序排序。要根据需要进行排序,您应该在插入或更新数据之前格式化数据。假设每个级别的最大数字为3,您的数据应该像这样格式化

 003.001
 003.001.001
 003.001.001.001
 003.002
 003.002.001
 003.002.001.001
 003.010
 010.001

替代方法是将“strand”列拆分为多列。每列将存储每个级别的数据,例如

Level1 | Level2 | Level3 ... 
3      | 1      | 0
3      | 1      | 1
3      | 2      | 0
...
3      | 10     | 0

这些列的数据类型应该是数字,然后您应该能够按这些列排序。

答案 4 :(得分:0)

试试这个:

DROP TABLE T1;
CREATE TABLE T1 (Strand VARCHAR(20));
INSERT INTO T1 VALUES ('3.1');
INSERT INTO T1 VALUES('3.1.1');
INSERT INTO T1 VALUES('3.1.1.1');
INSERT INTO T1 VALUES('3.1.1.2');
INSERT INTO T1 VALUES('3.2');
INSERT INTO T1 VALUES('3.2.1');
INSERT INTO T1 VALUES('3.10');
INSERT INTO T1 VALUES('3.10.1');

SELECT * FROM T1 
ORDER BY STRAND;


SELECT *
  FROM T1 
  ORDER BY 
    CAST(SUBSTRING_INDEX(CONCAT(Strand+'.0.0.0.0','.',1) AS UNSIGNED INTEGER) *1000 +
    CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(Strand,'.0.0.0.0'),'.',2),'.',-1)  AS UNSIGNED INTEGER) *100 +
    CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(Strand,'.0.0.0.0'),'.',3),'.',-1) AS UNSIGNED INTEGER) *10 +
    CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(Strand,'.0.0.0.0'),'.',4),'.',-1)  AS UNSIGNED INTEGER)

输出未订购:

    Strand
1   3.1
2   3.1.1
3   3.1.1.1
4   3.1.1.2
5   3.10
6   3.10.1
7   3.2
8   3.2.1

输出订单:

    Strand
1   3.1
2   3.1.1
3   3.1.1.1
4   3.1.1.2
5   3.2
6   3.2.1
7   3.10
8   3.10.1