【问题标题】:Sort varchar with alpha numeric and special character values使用字母数字和特殊字符值对 varchar 进行排序
【发布时间】:2020-05-23 01:58:58
【问题描述】:

我有一个 invoice_number 字段为varchar(20)

我的选择查询为

SELECT Row_Number() OVER(ORDER BY case isnumeric(invoice_number) 
                                       when 1 then convert(bigint,invoice_num)
                                       else 99999999999999999999 
                                  end) As id, 
       name,
       submit_date,
       invoice_number,
       invoice_total,
       currency_code
FROM vw_invoice_report

这适用于一些场景,但我无法使其适用于所有 invoice_number 值,如下所示

f8ad2a28ddad4f6aa4df
0B849D69741145379079
20190313176617593442
ATOctober2000Promise
00100001010000000061
E285567EF0D0885E9160
SC1805000123000293
1999bernstyin2010
20600006307FFGMG
REVISED INVOICE F...
1111-2222(changzhou)
667339, 667340, 6...
18.12733562GAGA L...
IN-US01235055    ...
SSR-USD/426/2019 - 2
Nanny; Park Doug
184034
376840
376847-1
72692
72691
72690
72689

上面的一些数据我收到Error converting data type varchar to bigint.,有人可以帮我使它适用于上面的测试数据吗?

【问题讨论】:

标签: sql sql-server sql-server-2005


【解决方案1】:

您的问题是您的某些发票编号(例如20190313176617593442)对于BIGINT 数据类型来说太大了。您可以通过将值保留为字符串并使用 0 将数字填充到 20 位进行排序来解决此问题。例如:

SELECT Row_Number() OVER(ORDER BY case isnumeric(invoice_number) 
                                       when 1 then REPLACE(STR(invoice_number, 20), ' ', '0') 
                                       else '99999999999999999999'
                                  end) As id,

SQLFiddle上的演示(也显示转换后的发票编号)

更新

根据 OP cmets 和要排序的附加值,此查询应满足该要求:

SELECT Row_Number() OVER(ORDER BY case 
                                       when isnumeric(invoice_number) = 1 then RIGHT('00000000000000000000' + REPLACE(invoice_number, '.', ''), 20) 
                                       when invoice_number like '%[0-9]-[0-9]%' and invoice_number not like '%[^0-9]' then REPLACE(STR(REPLACE(invoice_number, '-', '.'), 20), ' ', '0')
                                       else '99999999999999999999'
                                  end) As id,
       invoice_number
FROM vw_invoice_report

Demo on SQLFiddle

【讨论】:

  • sqlfiddle.com/#!18/b0f8c/1 你的作品除了带有句点(。)的条目之外的大部分作品你能检查一下 SQLFiddle 的附加值吗
  • @RanPaul 你如何想要. 的发票号码。在他们排序?例如61.913 是否应该被视为 616191399999999999999999999
  • 它应该被视为 61913,带有破折号(-)的条目的排序顺序也是确定性的一种对此类条目进行排序的方法? sqlfiddle.com/#!18/8dc1b/1
  • @RanPaul 应该将376845-1 排序在200000600000 之前或之后?
  • 376845-1 应该排在200000 之后
【解决方案2】:

嗯。我在想这可能会做你想做的事:

row_number() over (order by (case when isnumeric(invoicenumber) = 1
                                  then len(invoicenumber)
                                  else 99999
                                  end
                            ),
                            invoicenumber
                  )

【讨论】:

  • 如何通过desc订购?还有99999的目的是什么
  • @Gordon Linoff 有。如果是数字,他有效地改变了按数字排序,如果是文本则改变了文本。 99999 是非数字长度的替代(你永远不会有一个比那么多数字长的数字,所以这些数字总是在数字值之后)。如果您希望降序,您可以将 desc 放在第一个和第二个 order by 之后。
猜你喜欢
  • 2023-03-06
  • 2020-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多