Тип таблицы CONNECT XCOL
Таблицы XCOL основаны на другой таблице или представлении, например, на таблицах PROXY. Этот тип может быть использован, когда таблица-объект содержит столбец, содержащий список значений.
Предположим, у нас есть таблица 'children', которая может отображаться следующим образом:
| Имя | Список детей |
|---|---|
| София | Вивиан, Антони |
| Лизабет | Люси, Чарльз, Диана |
| Коринна | |
| Клод | Марк |
| Джейн | Артур, Сандра, Питер, Джон |
Мы можем иметь другое представление этих данных, где каждый ребёнок будет связан со своей матерью, создав таблицу XCOL следующим образом:
CREATE TABLE xchild ( mother char(12) NOT NULL, child char(12) DEFAULT NULL flag=2 ) ENGINE=CONNECT table_type=XCOL tabname='chlist' option_list='colname=child';
Опция COLNAME указывает имя столбца, который будет получать элементы списка. Это вернёт:
select * from xchild;
Запрошенное представление:
| Мать | Ребёнок |
|---|---|
| София | Вивиан |
| София | Антони |
| Лизабет | Люси |
| Лизабет | Чарльз |
| Лизабет | Диана |
| Коринна | NULL |
| Клод | Марк |
| Джейн | Артур |
| Джейн | Сандра |
| Джейн | Питер |
| Джейн | Джон |
Некоторые моменты следует отметить:
- Если исходное поле children пустое, то результат зависит от спецификации NULL для столбца "multiple". Если он допускает NULL, как в данном случае, пустая строка сгенерирует значение NULL. Однако, если столбец не допускает NULL, строка вообще не будет сгенерирована.
- Пробелы после разделителя игнорируются.
- Копия исходных данных не создаётся. Обе таблицы используют одни и те же исходные данные.
- Указание определений столбцов в инструкции
CREATE TABLEнеобязательно.
Столбец child в столбце "multiple" можно использовать как любой другой столбец. Например:
select * from xchild where substr(child,1,1) = 'A';
Это вернёт:
| Мать | Ребёнок |
|---|---|
| София | Антони |
| Джейн | Артур |
Если запрос не включает столбец "multiple", умножение строк не будет производиться. Например:
select mother from xchild;
Это просто вернёт всех матерей:
| Мать |
|---|
| София |
| Лизабет |
| Коринна |
| Клод |
| Джейн |
То же самое происходит с другими типами инструкций select, например:
select count(*) from xchild; -- returns 5 select count(child) from xchild; -- returns 10 select count(mother) from xchild; -- returns 5
Группировка также даёт разные результаты:
select mother, count(*) from xchild group by mother;
Результаты:
| Мать | count(*) |
|---|---|
| Клод | 1 |
| Коринна | 1 |
| Джейн | 1 |
| Лизабет | 1 |
| София | 1 |
В то время как запрос:
select mother, count(child) from xchild group by mother;
Даёт более интересный результат:
| Мать | count(ребёнок) |
|---|---|
| Клод | 1 |
| Коринна | 0 |
| Джейн | 4 |
| Лизабет | 3 |
| София | 2 |
Доступны некоторые дополнительные опции для этого типа таблиц:
| Опция | Описание |
|---|---|
| Sep_char | Символ разделителя, используемый в столбце "multiple", по умолчанию запятая. |
| Mult | Указывает максимальное количество элементов в списке. Используется для внутреннего расчёта максимального размера таблицы и по умолчанию равен 10. (Для указания в OPTION_LIST). |
Использование специальных столбцов с XCOL
В таблицах XCOL можно использовать специальные столбцы. Наиболее полезным является ROWNUM, который даёт ранг значения в списке значений. Например:
CREATE TABLE xchild2 ( rank int NOT NULL SPECIAL=ROWID, mother char(12) NOT NULL, child char(12) NOT NULL flag=2 ) ENGINE=CONNECT table_type=XCOL tabname='chlist' option_list='colname=child';
Эта таблица будет отображаться как:
| Ранг | Мать | Ребёнок |
|---|---|---|
| 1 | София | Вивиан |
| 2 | София | Антони |
| 1 | Лизабет | Люси |
| 2 | Лизабет | Чарльз |
| 3 | Лизабет | Диана |
| 1 | Клод | Марк |
| 1 | Джейн | Артур |
| 2 | Джейн | Сандра |
| 3 | Джейн | Питер |
| 4 | Джейн | Джон |
Чтобы вывести только первого ребёнка каждой матери, можно сделать:
SELECT mother, child FROM xchild2 where rank = 1 ;
возвращая:
| Мать | Ребёнок |
|---|---|
| София | Вивиан |
| Лизабет | Люси |
| Клод | Марк |
| Джейн | Артур |
Однако, обратите внимание на следующую ошибку: попытка получить имена всех матерей, имеющих более 2 детей, не может быть выполнена следующим образом:
SELECT mother FROM xchild2 where rank > 2;
Это происходит потому, что без умножения строк значение rank всегда равно 1. Правильный способ получить этот результат более сложный, но не может использовать столбец ROWNUM:
SELECT mother FROM xchild2 group by mother having count(child) > 2;
XCOL таблицы на основе указанных представлений
Вместо указания имени таблицы-источника через опцию TABNAME, можно извлечь данные из «представления», определение которого задаётся в новой опции SRCDEF. Например:
create table xsvars engine=connect table_type=XCOL srcdef='show variables like "optimizer_switch"' option_list='Colname=Value';
Затем, например:
select value from xsvars limit 10;
Это отобразит что-то вроде:
| Значение |
|---|
| index_merge=on |
| index_merge_union=on |
| index_merge_sort_union=on |
| index_merge_intersection=on |
| index_merge_sort_intersection=off |
| engine_condition_pushdown=off |
| index_condition_pushdown=on |
| derived_merge=on |
| derived_with_keys=on |
| firstmatch=on |
Примечание: все таблицы XCOL являются только для чтения.
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/connect-xcol-table-type/