簡體   English   中英

按varchar類型的列排序

[英]Order by for column in varchar type

我有以下列 ,以升序排列,但在3.1而不是3.2之后采用3.10。

該列是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最后

您可以根據字段的整數值對結果排序。 您的代碼看起來像

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

在此代碼中,替換功能將清除圓點(。)
希望有幫助

您必須標准化每組數字

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)

如果數據中的point( . )不超過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中的演示

如您所見,我已按order by子句使用了replacelengthpow函數。

1) replace(Strand, '.', '')將為我們提供int編號,例如:
replace('3.10.1.1', '.', '') => 31011 ;
2) (3 + length(replace(Strand, '.', '')) - length(Strand))將為我們提供點數,該點數是最大點數減去點數在Strand的數,例如:
3.1 => 2;
3) pow將X的值返回到Y的冪;

因此樣本數據的計算方式如下:

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

通過這些數字,您將獲得正確的排序。

由於“鏈”列是文本數據,因此將按字母順序排序。 為了按需訂購,應在插入或更新數據之前對其進行格式化。 假設每個級別的最大位數為3,則數據的格式應如下所示

 003.001
 003.001.001
 003.001.001.001
 003.002
 003.002.001
 003.002.001.001
 003.010
 010.001

替代方法是將“鏈”列分成多個列。 每列將存儲每個級別的數據,例如

Level1 | Level2 | Level3 ... 
3      | 1      | 0
3      | 1      | 1
3      | 2      | 0
...
3      | 10     | 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM