【问题标题】:how to sort table which has varchar column having integer value with special characters如何对具有带有特殊字符的整数值的varchar列的表进行排序
【发布时间】:2017-05-28 10:46:51
【问题描述】:

如何对具有带有特殊字符的整数值的 varchar 列的表进行排序 我在数据库中有一个表,它有一个 varchar 类型的列,值就像 在这里我尝试了下面的mysql查询

   SELECT * FROM table order by CONVERT(seq_no,signed integer) ASC

我在这里得到这样的结果。

    1
    2
    3
    4
    5
    6
    6_1
    6_2
    6_1_1
    6_1_2
    7
    8
    8_1
    8_2
    8_1_1
    8_1_2
    8_2_1
    8_2_2

但结果应该如下所示。

    1
    2
    3
    4
    5
    6
    6_1
    6_1_1
    6_1_2
    6_2
    7
    8
    8_1
    8_1_1
    8_1_2
    8_2
    8_2_1
    8_2_2

我也试过这个查询,但没有得到准确的结果。

   SELECT * FROM table order by CONVERT(seq_no,signed integer) ASC,seq_no

【问题讨论】:

  • 为什么不按 seqno 订购?
  • @Giorgi Nakeuri 我也尝试使用 sqno,如果我有超过 10 行 - 使用 order by seqno 结果将是这样的 1, 10, 11, 12, 2, 3, 4 , 5 , 6、6_1、6_1_1、6_1_2、6_2、7、8 8_1、8_1_1 8_1_2、8_2、8_2_1、8_2_2、9。但结果应该是 1, 2, 3, 4 , 5 , 6 , 6_1 , 6_1_1 , 6_1_2 ,6_2 , 7 , 8 8_1 , 8_1_1 8_1_2 ,8_2, 8_2_1, 8_2_2, 9, 10, 11, 12
  • 是的,在这种情况下,常规订购将不起作用。你不觉得包含这个测试数据而不是你已经提供的数据更好吗?
  • 这里是测试数据sqlfiddle.com/#!9/bf1647/1
  • 你没有像 6_1_10 这样的数据吗?

标签: mysql sql


【解决方案1】:

你可以试试这样的:

select * 
from table
where id = 18
order by cast(replace(INSERT(colname, LOCATE('_', colname), CHAR_LENGTH('_'), '.'),'_','') as decimal(10,4))

这是如何工作的:

  • 首先,仅将第一个下划线替换为句点/点
  • 接下来,从值中删除所有其他下划线。
  • 最后,将数字转换为小数,然后按小数排序

例如“6_1_1”将首先变为“6.1_1”,然后是“6.11”。转换为数字后,这将大于 6.1,即转换前的 '6_1',小于 6.12 ('6_1_2) 并且小于 10。

注意:感谢 this answer 替换第一次出现位!

SQL Fiddle

【讨论】:

  • 我担心会发生这种情况。有什么方法可以改变你的数据结构来反映这种层次结构吗?看不出有什么合理的办法处理6_1_2_10!
  • @shree.pat18 这是新表,请查看sqlfiddle.com/#!9/2fde56/1
【解决方案2】:

我认为您应该将这些行转换为具有固定长度部分的行。 例如,让我们将其转换为 10 个字母长度的部分:

6_1_2 ->           000000000600000000010000000002
6123_1111_33333 -> 000000612300000011110000033333
1123_5555       -> 000000112300000055550000000000

在这种情况下,您可以按此字符串排序。您可以使用SUBSTRING_INDEX()LPAD() 函数:

SELECT * 
FROM Table1 
ORDER BY

CONCAT
(
LPAD(SUBSTRING_INDEX( concat(seq_no,'_') , '_', 1 ),10,'0')
,
LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX( concat(seq_no,'_') , '_', 2 ),'_',-1),10,'0') 
,
LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX( concat(seq_no,'_') , '_', 3 ),'_',-1),10,'0') 
,
LPAD(SUBSTRING_INDEX(SUBSTRING_INDEX( concat(seq_no,'_') , '_', 4 ),'_',-1),10,'0') 
)

SQLFiddle demo

【讨论】:

    【解决方案3】:

    试试这个查询:-

    ;WITH CTE AS
    (
     SELECT BatchNumber, CAST(CONCAT('<A>',REPLACE(BatchNumber,'_','</A><A>'),'</A>') AS XML) Xmlcol 
    , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) rnk 
     FROM ApplicationBatchNumbers
    )
    ,CTE1 AS
    (
    SELECT BatchNumber, SplittedString , rnk , ROW_NUMBER() OVER (PARTITION BY RNK ORDER BY (SELECT NULL)) finalrnk 
    FROM
        (SELECT * FROM CTE) s
    CROSS APPLY
        (
            SELECT ProjectData.D.value('.', 'smallint') as SplittedString
            FROM s.xmlcol.nodes('A') as ProjectData(D)
        ) a
    )
    SELECT BatchNumber FROM CTE1
    PIVOT ( MAX(SplittedString) FOR finalrnk IN ([1],[2],[3]) ) pvt
    

    【讨论】:

    • 它不是 sql server
    猜你喜欢
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 2020-05-23
    • 2016-09-13
    • 2021-06-03
    • 2012-05-25
    相关资源
    最近更新 更多