Как заказать строку с разделителями в SQL - PullRequest
2 голосов
/ 12 декабря 2011

Мне нужно правильно упорядочить строковый столбец, содержащий группу чисел с разделителями, например:

1
1.1
1.1.1
1.2
1.2.1
1.10
2
2.1

Эти числа используются для определения дерева: например, 1 и 2 являются узлами верхнего уровня, а 1.1, 1.2 и 1.10 являются непосредственными потомками 1. Дерево может быть сколь угодно глубоким, поэтому по сути не существует верхней границы для числа периодов в каждой записи (хотя на практике ограничение на количество символов в столбце будет обеспечивать это).

Проблема, с которой я сталкиваюсь, заключается в том, что стандартная операция ORDER BY в SQL будет перечислять 1.10 перед 1.2. Это, конечно, ожидается, но, к сожалению, не то, что я хочу, так как 10 > 2. Есть ли эффективный способ получить мой заказ? Я использую MySQL.

Обратите внимание, что я не обязательно использую эту кодировку для дерева, поэтому, если есть другая кодировка, которую проще заказать, чем смело предлагать ее. Тем не менее, одна приятная вещь, которую предлагает мне эта структура, - это простой способ восстановить все вышестоящие родительские узлы или все нижестоящие дочерние узлы за один проход, что не может работать с более типичной моделью row / parent_row (насколько это возможно). насколько я знаю). Например, учитывая идентификатор 1.2.1.4.5, я знаю, что четыре предка - 1, 1.2, 1.2.1 и 1.2.1.4, и все дети (как прямые потомки, так и дети детей) будут иметь идентификатор, который начинается с 1.2.1.4.5..

1 Ответ

0 голосов
/ 12 декабря 2011

@ Abiel, на основании вашего комментария, что каждый узел, вероятно, не имеет более 50 прямых дочерних элементов, и в этом случае (когда 62 дочерних узлов будет достаточно), как указано в комментарии @Bohemian, мы могли бы использовать компьютер -читаемый код 0-9A-Za-z ( Base 62 Encoding ), мы могли бы установить новый столбец VARCHAR( 255 ) BINARY, чтобы помочь нам с сортировкой.

CREATE TABLE  `test`.`tree` (
  `computer_readable` VARCHAR( 255 ) BINARY NOT NULL ,
  `human_readable` VARCHAR( 255 ) NOT NULL ,
  `title` VARCHAR( 255 ) NOT NULL ,
  PRIMARY KEY (  `computer_readable` ) ,
  INDEX (  `human_readable` )
);

Как вы уже могли заметить, столбец computer_readable определен как BINARY, поэтому мы можем иметь до 62 [0-9A-Za-z] (вместо 36 [0-9a-z]) дочерних узлов для каждого узла.

mysql> SELECT 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)

mysql> SELECT BINARY 'a' = 'A';
+------------------+
| BINARY 'a' = 'A' |
+------------------+
|                0 |
+------------------+
1 row in set (0.00 sec)

mysql> SELECT BINARY 'a' > 'A';
+------------------+
| BINARY 'a' > 'A' |
+------------------+
|                1 |
+------------------+
1 row in set (0.00 sec)

Итак, с этим новым полем мы могли бы получить данные в этом формате (указан в CSV ниже):

"1";"1";"Books"
"11";"1.1";"Fiction"
"111";"1.1.1";"Science-Fiction"
"12";"1.2";"Self-Help"
"121";"1.2.1";"Motivational"
"1A";"1.10";"Textbooks"
"1e";"1.40";"Coloring Books"
"2";"2";"Music"
"21";"2.1";"Classical"

Какой MySQL с удовольствием рассортирует нас

mysql> SELECT * FROM `tree` ORDER BY `computer_readable`;
+-------------------+----------------+-----------------+
| computer_readable | human_readable | title           |
+-------------------+----------------+-----------------+
| 1                 | 1              | Books           |
| 11                | 1.1            | Fiction         |
| 111               | 1.1.1          | Science-Fiction |
| 12                | 1.2            | Self-Help       |
| 121               | 1.2.1          | Motivational    |
| 1A                | 1.10           | Textbooks       |
| 1e                | 1.40           | Coloring Books  |
| 2                 | 2              | Music           |
| 21                | 2.1            | Classical       |
+-------------------+----------------+-----------------+
9 rows in set (0.00 sec)

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...