Сортировка varchar с альфа-цифрой c и значениями специальных символов - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть поле 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

, который отлично работает для нескольких сценариев ios, но я не смог его сделать работать для всех значений 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. для некоторых из вышеперечисленных данных, может кто-нибудь, пожалуйста, помогите мне заставить его работать для вышеуказанных тестовых данных?

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Ваша проблема в том, что некоторые номера ваших счетов (например, 20190313176617593442) слишком велики для типа данных BIGINT. Вы можете обойти это, сохраняя значения в виде строк и оставляя отступы с 0 цифрами c до 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 комментарии и дополнительные значения для сортировки, этот запрос должен удовлетворять этому требованию:

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

Демонстрация по SQLFiddle

0 голосов
/ 07 февраля 2020

Хммм. Я думаю, что это может сделать то, что вы хотите:

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