1 Востаннє редагувалося fed_lviv (07.03.2015 20:20:13)

Тема: MySQL "ORDER BY CAST(varchar AS int)"

Допоможіть будь-ласка з сортуванням. Є таблиця, з якої вибирається значення з поля (VARCHAR), потрібно значення відсортувати. Значення, типове (ТП-12, ТП-512, ТП-112). Тобто зпочатку дві літери, потім дефіс, потім число (від двох цифр до чотирьох). Хочу, щоб "правильно": ТП-12, ТП-112, ТП-512.

SELECT number FROM ts ORDER BY number
SELECT number FROM ts ORDER BY number*1
SELECT number FROM ts ORDER BY CAST(number AS UNSIGNED)

Один варіант тільки підійшов, але чи можна, якось "простіше"?

SELECT number FROM ts ORDER BY CAST(SUBSTRING(number,4) AS UNSIGNED)

Є, якісь інші варіанти, підкажіть?

2 Востаннє редагувалося leofun01 (07.03.2015 20:59:54)

Re: MySQL "ORDER BY CAST(varchar AS int)"

Якщо поле містить стрічку, яка завжди має формат "CC-N" (де C - буква, N - число), то варто розбити це поле на 2 нові: varchar(2) і smallint (або int). І проблема зникне і буде зручніше писати запити.
Чи у вас немає можливості змінювати таблиці бд ?

Подякували: koala1

3

Re: MySQL "ORDER BY CAST(varchar AS int)"

1НФ вимагає атомарності кожного атрибуту. У вас же це поле містить, фактично, два - літери і числа. Нормалізуйте базу і проблема зникну (як саме - вже сказав leofun01). Можете додатково створити VIEW із потрібною вам агрегацією полів.

4 Востаннє редагувалося Vo_Vik (08.03.2015 04:07:25)

Re: MySQL "ORDER BY CAST(varchar AS int)"

fed_lviv написав:

Допоможіть будь-ласка з сортуванням. Є таблиця, з якої вибирається значення з поля (VARCHAR), потрібно значення відсортувати. Значення, типове (ТП-12, ТП-512, ТП-112). Тобто зпочатку дві літери, потім дефіс, потім число (від двох цифр до чотирьох). Хочу, щоб "правильно": ТП-12, ТП-112, ТП-512.

SELECT number FROM ts ORDER BY number
SELECT number FROM ts ORDER BY number*1
SELECT number FROM ts ORDER BY CAST(number AS UNSIGNED)

Один варіант тільки підійшов, але чи можна, якось "простіше"?

SELECT number FROM ts ORDER BY CAST(SUBSTRING(number,4) AS UNSIGNED)

Є, якісь інші варіанти, підкажіть?

Тут проблема в тому що там є дифіз, тобто воно бере не цифри, а -12 і -512 і так далі. Попробуйте використовувати CAST(number AS SIGNED)
А ще краще добавте каст в результати виборки, щоб бачити що він вам повертає:

SELECT number, CAST(number AS SIGNED) FROM ts ORDER BY CAST(number AS SIGNED)

5

Re: MySQL "ORDER BY CAST(varchar AS int)"

leofun01 написав:

Якщо поле містить стрічку, яка завжди має формат "CC-N" (де C - буква, N - число), то варто розбити це поле на 2 нові: varchar(2) і smallint (або int). І проблема зникне і буде зручніше писати запити.
Чи у вас немає можливості змінювати таблиці бд ?

Наразі змінювати БД немає можливості, тому в мене тільки один вихід правильний запит.

6

Re: MySQL "ORDER BY CAST(varchar AS int)"

Не впевнений, що все пройде гладко, але здається що тут ще можна використати функцію REVERSE()

SELECT number FROM ts ORDER BY REVERSE(number)

7

Re: MySQL "ORDER BY CAST(varchar AS int)"

Ні, функція REVERSE() абсолютно тут не підходить, щойно перевірив

select 'ТП-117', REVERSE('ТП-117') res
union
select 'ТП-512', REVERSE('ТП-512')
union
select 'ТП-12', REVERSE('ТП-12')
order by 2

8 Востаннє редагувалося ConTrast77 (26.03.2015 20:33:29)

Re: MySQL "ORDER BY CAST(varchar AS int)"

SELECT char_number FROM ts ORDER BY LENGTH(char_number)ASC


Ще спробуйте

SELECT char_number FROM ts ORDER BY LENGTH(char_number) ASC, char_number ASC
SELECT char_number FROM ts ORDER BY LENGTH(char_number), char_number ASC

думаю lenght якраз спочатку поставить більш короткі однотипні назви (тобто наприклад все що ТП-10..ТП-99)

ТП-12
ТП-117
ТП-512
ТП-1212

відповідно цього
http://www.peachpit.com/articles/articl … p;seqNum=4
Tips/ Listing 4.15. - до ORDER BY можна вказувати умови (стовпчики), які не є в переліку стовпчиків до показу, але йдуть до фільтру згідно додаткових умов.


і ось така вигадка
- з використанням первинних значень як нумерований сортирований перелік з допомогою CASE when LIKE

SELECT char_number FROM ts ORDER BY
case 
    when name LIKE "ТП-%" then 1
    when name LIKE "ТПП-%"  then 2
    when name LIKE "БК-%"  then 3
    else 4
end,
LENGTH(char_number), char_number ASC

- щоб ця магія запрацювала - треба дещо зачарувати, очевидним жестом


Джерело примірників
http://www.sql.ru/forum/626794/opredeli … sya-simvol
http://stackoverflow.com/questions/2572 … ize-length - замість поля VARCHAR() поле TEXT
http://rgblog.ru/page/sekrety-sortirovki-v-mysql

P.S. Лайк- за магію, та будеш ще трохи винен.
"за магию нужно платить" (с) Румпельштицкен, (Once Upon a Time)
http://yoursmileys.ru/tsmile/money/t3907.gif