Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сортировка с использованием SUBSTRING_INDEX / 25 сообщений из 32, страница 1 из 2
26.10.2015, 00:06:51
    #39086278
vedroide2e4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Доброго времени суток,

столкнулся с задачей сортировки таблицы адресов. Таблица представляет собой набор названий домов вида:

name
-------
15k1
15k4
15k3
15k2
31k1
31k3
31k4
31k2

Чтобы корректно отсортировать по номерам домов использовал:
Код: sql
1.
ORDER BY (name+0)


Не могу осилить дополнительную сортировку по номерам корпусов, чтобы получить результат вида 15k1;15k2;15k3. Думаю, нужно использовать SUBSTRING_INDEX, но не понятно как именно
...
Рейтинг: 0 / 0
26.10.2015, 00:16:36
    #39086281
Alex_Ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
использовать то вот так
SUBSTRING_INDEX(name,"к", -1)+0
(-1 - это до первой "к" справа)
но это затычка...
...
Рейтинг: 0 / 0
26.10.2015, 00:24:24
    #39086284
vedroide2e4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Alex_Ustinov,
в таком случае сортировка идет только по части строки после разделителя
...
Рейтинг: 0 / 0
26.10.2015, 01:07:22
    #39086297
Alex_Ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
ну это я добавил плюсом к вашей сортировке...
это все не есть хорошо - сортировка по "функции" на больших данных это будет не быстро
можно сделать сортировку и по REPLACE(name,"к","")
но все дело в количестве цифр в номере дома и номере корпуса (9к1 будет "дальше чем" 10к4 при сравнении строк)
1. для простоты делают доп.поле с фиксированной длиной (дополнением нулей ) для дома и корпуса, т.е. дома 9к4 15к5 будут выглядеть как 00904 01505. триггером заполнить. Или изначально хранят в таком виде с парсингом на клиенте
2. разбить на два поля - номер дома и корпуса
...
Рейтинг: 0 / 0
26.10.2015, 01:15:59
    #39086299
Alex_Ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
... ваш пробка для "бутылки с шампанским"
Код: sql
1.
order by name+0, SUBSTRING_INDEX(name,"к", -1)+0


и еще куча вариантов приведения строки к фрматированному виду
...
Рейтинг: 0 / 0
26.10.2015, 10:10:19
    #39086452
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
vedroide2e4,

Всегда ли присутствует вторая часть в номере дома и всегда ли разделитель "к" ?
...
Рейтинг: 0 / 0
26.10.2015, 10:18:19
    #39086461
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
vedroide2e4Не могу осилить дополнительную сортировку по номерам корпусов
А почему бы не подойти к вопросу системно? нормализовать данные проще, чем заниматься этой фигнёй...
...
Рейтинг: 0 / 0
26.10.2015, 10:23:12
    #39086470
Alex_Ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
ну и извечная проблема, которую следует учесть - ЛИТЕР дома (14а 15б), это куда отнести, к номеру дома или как корпус?
может такое быть <дом 24 литер "а" корпус 3> ? я не изучал данный вопрос
Надо тоже продумывать сразу
...
Рейтинг: 0 / 0
26.10.2015, 10:28:50
    #39086473
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Akinaнормализовать данные прощеЗависит от задачи. Если это один город, где все номера заранее известны, то да, проще. А в общемировом масштабе там такое встречается, что никакой нормализации не хватит.
...
Рейтинг: 0 / 0
26.10.2015, 11:16:47
    #39086554
vedroide2e4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Alex_Ustinov... ваш пробка для "бутылки с шампанским"
Код: sql
1.
order by name+0, SUBSTRING_INDEX(name,"к", -1)+0


и еще куча вариантов приведения строки к фрматированному виду
Спасибо за рабочее решение. Может, вы и более детально сможете мне ответить. В ситуации, если в таблице присутствуют записи без "kN", например, 15;15k4;15k3; 31;31k4;31k2, предложенный вами вариант сортировки располагает значения без "kN" в конце каждой группы. Логика понятно, но для человека это не очень удобно. Можно ли поместить значения без "kN" в начало?

miksoftvedroide2e4,

Всегда ли присутствует вторая часть в номере дома и всегда ли разделитель "к" ?
Нет, не всегда. Возможен так же вариант с "/" и без разделителя (случаи с Литерой, а не корпусом)

Akinavedroide2e4Не могу осилить дополнительную сортировку по номерам корпусов
А почему бы не подойти к вопросу системно? нормализовать данные проще, чем заниматься этой фигнёй...
Я отталкиваюсь от данности, когда существует массив данных, с которым уже работают. Если я начну переделывать структуру БД и таблиц для данной задачи, то придется менять существующую реализацию всех остальных.
...
Рейтинг: 0 / 0
26.10.2015, 11:35:02
    #39086594
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
vedroide2e4Я отталкиваюсь от данности, когда существует массив данных, с которым уже работают.
В таком случае Вы уже располагаете ВСЕМИ вариантами. И можете их шаблонизировать.
Два варианта уже показаны:
"NNN"
"NNNкMMM"
где NNN и MMM - группы цифр неопределённой длины.
Какие ещё есть варианты? дайте исчерпывающий список. Тогда можно будет создавать универсальный код требуемой сортировки.
Впрочем, он скорее всего будет опираться на один из двух подходов. Первый - это последовательное выделение групп и последовательная же сортировка по значению группы. Второй - это удаление разделителей и приведение групп к постоянной длине с выравниванием вправо и последующая сортировка как строки.
Заодно определитесь, как следует сортировать, например, такую группу:
15
15/1
15к1
...
Рейтинг: 0 / 0
26.10.2015, 11:46:08
    #39086613
vedroide2e4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Akinaдайте исчерпывающий список.
Если говорить о всех возможных вариантах и желаемой сортировке:
15;15k1;15k2;15A;15B;15/1;15/2, т.е. "NNN";"NNNкMMM";"NNNOOO";"NNN/PPP"
...
Рейтинг: 0 / 0
26.10.2015, 12:27:28
    #39086677
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Alex_Ustinovможет такое быть <дом 24 литер "а" корпус 3> ? я не изучал данный вопросСам такого не встречал, но одна госконтора использует такой формат адресов:
Код: plaintext
1.
2.
3.
4.
<ФИАС-овские коды вплоть до улицы/доп.территории>
house_number Номер дома
building Строение
block Корпус
letter Литера
Так что скоре всего может.
...
Рейтинг: 0 / 0
26.10.2015, 12:39:44
    #39086696
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
mysql> create table test(num varchar(16));
Query OK, 0 rows affected (0.32 sec)

mysql> insert into test (num)
    -> select '15' union all
    -> select '15k1' union all
    -> select '15k2' union all
    -> select '15A' union all
    -> select '15B' union all
    -> select '15/1' union all
    -> select '15/2' ;
Query OK, 7 rows affected (0.07 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> select * from test
    -> order by
    -> case
    -> when num = cast(num+0 as char) then 1
    -> when locate('k', num) then 2
    -> when locate('/', num) then 4
    -> else 3 end ,
    -> num
    -> ;
+------+
| num  |
+------+
| 15   |
| 15k1 |
| 15k2 |
| 15A  |
| 15B  |
| 15/1 |
| 15/2 |
+------+
7 rows in set, 2 warnings (0.01 sec)
...
Рейтинг: 0 / 0
26.10.2015, 12:43:43
    #39086702
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Правда, в примере все дома - 15-е. Чтобы и другие сортировать правильно - первым этапом поставить order by num+0, а потом уже всё остальное.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
mysql> insert into test select replace(num,'15','31') from test order by num;
Query OK, 7 rows affected (0.09 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> select * from test;
+------+
| num  |
+------+
| 15   |
| 15k1 |
| 15k2 |
| 15A  |
| 15B  |
| 15/1 |
| 15/2 |
| 31   |
| 31/1 |
| 31/2 |
| 31A  |
| 31B  |
| 31k1 |
| 31k2 |
+------+
14 rows in set (0.00 sec)

mysql> select * from test
    -> order by
    -> num+0,
    -> case
    -> when num = cast(num+0 as char) then 1
    -> when locate('k', num) then 2
    -> when locate('/', num) then 4
    -> else 3 end ,
    -> num
    -> ;
+------+
| num  |
+------+
| 15   |
| 15k1 |
| 15k2 |
| 15A  |
| 15B  |
| 15/1 |
| 15/2 |
| 31   |
| 31k1 |
| 31k2 |
| 31A  |
| 31B  |
| 31/1 |
| 31/2 |
+------+
14 rows in set, 8 warnings (0.00 sec)
...
Рейтинг: 0 / 0
26.10.2015, 12:45:42
    #39086705
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Правда, код НЕ учитывает, что номера после "k" или "/" могут быть более одной цифры. Но это можно подрихтовать выделением подстроки и кастом в число.
...
Рейтинг: 0 / 0
26.10.2015, 13:13:37
    #39086765
DBConstructor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
vedroide2e4, почему бы вам просто не использовать классификатор адресов ГНИВЦ?
http://www.gnivc.ru/inf_provision/classifiers_reference/kladr/
...
Рейтинг: 0 / 0
26.10.2015, 14:01:29
    #39086836
Alex_Ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
DBConstructor,

это вроде оттуда и есть, там примерно так же хранятся
...
Рейтинг: 0 / 0
26.10.2015, 14:19:59
    #39086864
vedroide2e4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
DBConstructor , потому как далеко не все его используют. Соответственно, для использования классификатора нужно данные сначала приводить в нужный вид. А вообще про КЛАДР я подумал в первую очередь. У меня же задача состоит в сортировке того, что имеем.
...
Рейтинг: 0 / 0
26.10.2015, 14:23:08
    #39086871
vedroide2e4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
AkinaПравда, код НЕ учитывает, что номера после "k" или "/" могут быть более одной цифры. Но это можно подрихтовать выделением подстроки и кастом в число.
Akina, ваш код прекрасно работает, огромное спасибо.
Вы можете наглядно показать то, что вы назвали подрихтовкой? Вы говорите про вариант, когда мы имеем 15k1,15k11,15k2,15k21,15k3?
...
Рейтинг: 0 / 0
26.10.2015, 14:54:25
    #39086937
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
vedroide2e4Вы говорите про вариант, когда мы имеем 15k1,15k11,15k2,15k21,15k3?
Именно. Просто в этом случае в третьем слое вместо просто num нужно использовать выделяемую подстроку после разделитела ("k" либо "/"). Короче, ещё один CASE.
...
Рейтинг: 0 / 0
26.10.2015, 16:00:14
    #39087072
vedroide2e4
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
Akinavedroide2e4Вы говорите про вариант, когда мы имеем 15k1,15k11,15k2,15k21,15k3?
Именно. Просто в этом случае в третьем слое вместо просто num нужно использовать выделяемую подстроку после разделитела ("k" либо "/"). Короче, ещё один CASE.
Akina, не могли бы вы показать наглядно? Выделяем подстроку с помощью SUBSTRING_INDEX(num,'k' -1) или SUBSTRING_INDEX(num,'/' -1)?
...
Рейтинг: 0 / 0
26.10.2015, 16:07:08
    #39087086
Alex_Ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
не забывайте,
SELECT SUBSTRING_INDEX("12345678","k",-1) = "12345678"
без найденной подстроки вернет строку полностью
...
Рейтинг: 0 / 0
26.10.2015, 16:11:58
    #39087100
Alex_Ustinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
tanglir,

...ФИАС-вские...

ну это разумно, даже если вариантов Литера-корпус нет
...
Рейтинг: 0 / 0
26.10.2015, 17:18:56
    #39087214
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сортировка с использованием SUBSTRING_INDEX
vedroide2e4не могли бы вы показать наглядно?
Я показал запрос. И там в ORDER BY есть вполне себе наглядный CASE.

vedroide2e4Выделяем подстроку с помощью SUBSTRING_INDEX(num,'k' -1) или SUBSTRING_INDEX(num,'/' -1)?
Угу. И не забываем прибавить нолик.

Alex_Ustinovне забывайте,
SELECT SUBSTRING_INDEX("12345678","k",-1) = "12345678"
без найденной подстроки вернет строку полностью
Внутри CASE пофиг - на обработку поступают только записи, гарантированно содержащие литерал-разделитель.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сортировка с использованием SUBSTRING_INDEX / 25 сообщений из 32, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]