Spec-Zone.ru › MariaDB

Тип таблицы CONNECT PIVOT

Этот тип таблицы может быть использован для преобразования результата другой таблицы или представления (называемой исходной таблицей) в сводную таблицу по столбцам «pivot» и «facts». Сводная таблица — это удобный инструмент для отчётов, который сортирует и суммирует (по умолчанию) независимо от исходной структуры данных в исходной таблице.

Например, предположим, что у вас есть следующая таблица «Expenses»:

Кто Неделя Что Сумма
Джо 3 Пиво 18.00
Бет 4 Еда 17.00
Джейн 5 Пиво 14.00
Джо 3 Еда 12.00
Джо 4 Пиво 19.00
Джейн 5 Машина 12.00
Джо 3 Еда 19.00
Бет 4 Пиво 15.00
Джейн 5 Пиво 19.00
Джо 3 Машина 20.00
Джо 4 Пиво 16.00
Бет 5 Еда 12.00
Бет 3 Пиво 16.00
Джо 4 Еда 17.00
Джо 5 Пиво 14.00
Джейн 3 Машина 19.00
Джо 4 Еда 17.00
Бет 5 Пиво 20.00
Джейн 3 Еда 18.00
Джо 4 Пиво 14.00
Джо 5 Еда 12.00
Джейн 3 Пиво 18.00
Джейн 4 Машина 17.00
Джейн 5 Еда 12.00

Преобразование содержимого таблицы, используя поля «Кто» и «Неделя» для левых столбцов, и поле «Что» для верхних заголовков, а также суммирование полей «Сумма» для каждой ячейки в новой таблице, даёт следующий желаемый результат:

Кто Неделя Пиво Машина Еда
Бет 3 16.00 0.00 0.00
Бет 4 15.00 0.00 17.00
Бет 5 20.00 0.00 12.00
Джейн 3 18.00 19.00 18.00
Джейн 4 0.00 17.00 0.00
Джейн 5 19.00 12.00 12.00
Джо 3 18.00 20.00 31.00
Джо 4 19.00 0.00 34.00
Джо 5 14.00 0.00 12.00

Обратите внимание, что SQL позволяет получить тот же результат, но по-другому, используя предложение «group by»:

select who, week, what, sum(amount) from expenses
       group by who, week, what;

Однако нет способа получить представленную выше сводную структуру только с помощью SQL. Даже использование встроенного SQL-программирования для некоторых СУБД не совсем просто и автоматизировано.

Тип сводной таблицы CONNECT делает это намного проще.

Использование типа сводных таблиц

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

create table pivex
engine=connect table_type=pivot tabname=expenses;

Теперь вы можете использовать её как любую другую таблицу, например, для отображения результата, показанного выше, просто скажите:

select * from pivex;

Реализация типа сводной таблицы CONNECT выполняет большую часть работы по преобразованию исходной таблицы:

  1. Нахождение столбца «Facts», по умолчанию последний столбец исходной таблицы. Нахождение столбцов «Facts» или «Pivot» работает только для сводных таблиц на основе таблиц. Они не работают для сводных таблиц на основе представлений или srcdef, для которых они должны быть явно указаны.
  2. Нахождение столбца «Pivot», по умолчанию оставшийся столбец.
  3. Выбор агрегатной функции для использования, «SUM» по умолчанию.
  4. Построение и выполнение «Group By» по столбцу «Facts», получение результата в памяти.
  5. Получение всех уникальных значений в столбце «Pivot» и определение столбца «Data» для каждого.
  6. Распространение результата промежуточной таблицы памяти в итоговую таблицу.

Столбец «Pivot» исходной таблицы не должен быть nullable (нет таких вещей как столбец «null»). Создание будет отклонено, даже если этот nullable столбец фактически не содержит нулевых значений.

Если требуется другой результат, доступны параметры Create Table для изменения значений по умолчанию, используемых Pivot. Например, если мы хотим отобразить средние расходы для каждого человека и продукта, распределённые по столбцам для каждой недели, используйте следующий оператор:

create table pivex2
engine=connect table_type=pivot tabname=expenses
option_list='PivotCol=Week,Function=AVG';

Теперь, сказав:

select * from pivex2;

Будет отображена результирующая таблица:

Кто Что 3 4 5
Бет Пиво 16.00 15.00 20.00
Бет Еда 0.00 17.00 12.00
Джейн Пиво 18.00 0.00 16.50
Джейн Машина 19.00 17.00 12.00
Джейн Еда 18.00 0.00 12.00
Джо Пиво 18.00 16.33 14.00
Джо Машина 20.00 0.00 0.00
Джо Еда 15.50 17.00 12.00

Ограничение столбцов в сводной таблице

Предположим, что нам нужна сводная таблица расходов, суммирующая расходы всех людей и продуктов независимо от недели покупки. Это можно сделать, просто удалив столбец недели из списка столбцов в таблице pivex.

alter table pivex drop column week;

Результат, который мы получаем от новой таблицы:

Кто Пиво Машина Еда
Бет 51.00 0.00 29.00
Джейн 51.00 48.00 30.00
Джо 81.00 20.00 77.00

Примечание: Ограничение столбцов также необходимо, когда исходная таблица содержит дополнительные столбцы, которые не должны быть частью сводной таблицы. Это особенно верно для ключевых столбцов, которые препятствуют правильному группированию.

Синтаксис оператора CREATE TABLE для сводных таблиц

Оператор CREATE TABLE для сводных таблиц использует следующий синтаксис:

create table pivot_table_name
[(column_definition)]
engine=CONNECT table_type=PIVOT
{tabname='source_table_name' | srcdef='source_table_def'}
[option_list='pivot_table_option_list'];

Определение столбцов имеет два набора столбцов:

  1. Набор столбцов, принадлежащих исходной таблице, не включая столбцы «facts» и «pivot».
  2. Столбцы «Data», получающие значения агрегированных столбцов «facts», имеющие названия из значений столбца «pivot». Они обозначаются опцией «flag».

Доступные опции и подопции для сводных таблиц:

Опция Тип Описание
ИмяТаблицы [БД.]Имя Имя таблицы для «свода». Если не задано, SrcDef должно быть указано.
SrcDef SQL_оператор Оператор, используемый для создания промежуточной mysql таблицы.
ИмяБД имя Имя базы данных, содержащей исходную таблицу. По умолчанию используется текущая база данных.
Функция* имя Имя агрегатной функции, используемой для столбцов данных, SUM по умолчанию.
PivotCol* имя Указывает имя столбца Pivot, значения которого используются для заполнения столбцов «data», имеющих опцию «flag».
FncCol* [func(]имя[)] Указывает имя столбца данных «Facts». Если используется форма func(имя), имя агрегатной функции устанавливается в func.
Groupby* Булево Установите его в True (1 или Yes), если таблица уже имеет формат GROUP BY.
Accept* Булево Принимать несовпадающие значения столбца Pivot.
  • : Эти опции должны быть указаны в OPTION_LIST.

Дополнительные параметры доступа

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

1. Исходная таблица не является таблицей CONNECT. 2. Указана опция SrcDef. 3. Исходная таблица находится на другом сервере. 4. Столбцы не указаны.

По умолчанию Pivot пытается вызвать текущий сервер, используя host=localhost, user=root без пароля и port=3306. Однако это может не соответствовать требованиям, особенно если у локального пользователя root есть пароль, в этом случае может появиться сообщение об ошибке «access denied» при создании или использовании сводной таблицы.

Укажите опции host, user, password и/или port в списке параметров, чтобы переопределить параметры подключения по умолчанию, используемые для доступа к исходной таблице, получения спецификаций столбцов, выполнения сгенерированного запроса group by или SrcDef.

Определение сводной таблицы

Существуют два основных способа определения сводной таблицы:

1. Из существующей таблицы или представления. 2. Непосредственно указав SQL-оператор, возвращающий результат в Pivot.

Определение сводной таблицы из исходной таблицы

Стандартная опция таблицы tabname используется для указания имени исходной таблицы или представления.

Для таблиц внутренний Group By будет генерироваться внутри, за исключением случаев, когда опция GROUPBY задана как true. Делайте это только тогда, когда таблица или представление имеет правильный формат GROUP BY.

Непосредственное определение источника сводной таблицы в SQL

В качестве альтернативы, внутренний источник может быть непосредственно определён с помощью опции SrcDef, которая должна иметь правильный формат group by.

Как мы видели выше, правильная сводная таблица создаётся из внутренней промежуточной таблицы, полученной в результате выполнения оператора GROUP BY. Во многих случаях проще или желательно указать это напрямую при создании сводной таблицы. Это может быть потому, что источник является результатом сложного процесса, включающего фильтрацию и/или объединение таблиц.

Для этого используйте опцию SrcDef, часто заменяя все остальные опции. Например, предположим, что в первом примере нас интересуют только недели 4 и 5. Мы можем, конечно, отобразить это, используя:

select * from pivex where week in (4,5);

Однако, что если эта таблица огромна? В этом случае правильный способ сделать это — определить сводную таблицу следующим образом:

create table pivex4
engine=connect table_type=pivot
option_list='PivotCol=what,FncCol=amount'
SrcDef='select who, week, what, sum(amount) from expenses
where week in (4,5) group by who, week, what';

Если ваша исходная таблица содержит миллионы записей, а вы планируете преобразовать только небольшую часть из них, это существенно повлияет на производительность. Кроме того, вы имеете полную свободу использовать выражения, скалярные функции, псевдонимы, объединения, условия where и having в вашем SQL-запросе. Единственное ограничение заключается в том, что вы несете ответственность за то, чтобы результат этого запроса имел правильный формат для обработки сводки.

Использование SrcDef также позволяет использовать выражения и/или скалярные функции. Например:

create table xpivot (
Who char(10) not null,
What char(12) not null,
First double(8,2) flag=1,
Middle double(8,2) flag=1,
Last double(8,2) flag=1)
engine=connect table_type=PIVOT
option_list='PivotCol=wk,FncCol=amnt'
Srcdef='select who, what, case when week=3 then ''First'' when
week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) *
6.56 as amnt from expenses group by who, what, wk';

Теперь запрос:

select * from xpivot;

Выведет результат:

Кто Что Первый Средний Последний
Beth Пиво 104.96 98.40 131.20
Beth Еда 0.00 111.52 78.72
Janet Пиво 118.08 0.00 216.48
Janet Авто 124.64 111.52 78.72
Janet Еда 118.08 0.00 78.72
Joe Пиво 118.08 321.44 91.84
Joe Авто 131.20 0.00 0.00
Joe Еда 203.36 223.04 78.72

Примечание 1: чтобы избежать нескольких строк с одинаковыми значениями фиксированных столбцов, в SrcDef обязательно следует размещать столбец сводки в конце списка group by.

Примечание 2: в операторе создания SrcDef обязательно необходимо присваивать псевдонимы столбцам, содержащим выражения, чтобы они распознавались другими опциями.

Примечание 3: в операторе выбора SrcDef кавычки необходимо экранировать, поскольку весь оператор передаётся MariaDB в кавычках. В качестве альтернативы, укажите его в двойных кавычках.

Примечание 4: Мы могли бы оставить CONNECT для определения столбцов. Однако, поскольку они определены по отсортированным именам, столбец Средний был помещен в конец.

Указание столбцов, соответствующих столбцу сводки

Эти столбцы должны быть названы по значениям, присутствующим в столбце «pivot». Например, предположим, что у нас есть следующая таблица pet:

Имя Порода Количество
John собака 2
Bill кот 1
Mary собака 1
Mary кот 1
Lisbeth кролик 2
Kevin кот 2
Kevin птица 6
Donald собака 1
Donald рыба 3

Преобразование его с использованием Порода в качестве столбца сводки выполняется с помощью:

create table pivet
engine=connect table_type=pivot tabname=pet
option_list='PivotCol=race,groupby=1';

Это даёт результат:

Имя Собака Кот Кролик Птица Рыба
John 2 0 0 0 0
Bill 0 1 0 0 0
Mary 1 1 0 0 0
Lisbeth 0 0 2 0 0
Kevin 0 2 0 6 0
Donald 1 0 0 0 3

Кстати, это вам о чём-то говорит? Это показывает, что сводные таблицы в некотором роде выполняют обратные действия по сравнению с таблицами OCCUR.

Мы можем альтернативно определить конкретно столбцы таблицы, но что произойдёт, если столбец Сводки содержит значения, не соответствующие столбцу «данных»? Существует три случая в зависимости от указанных параметров и флагов.

Первый случай: Если не указано никаких конкретных параметров, это ошибка, и при попытке отобразить таблицу запрос прервётся с сообщением об ошибке, указывающим, что было встречено несоответствующее значение. Обратите внимание, что поскольку список столбцов формируется при создании таблицы, это может произойти, если в исходную таблицу вставлены строки, содержащие новые значения для столбца сводки. В этом случае следует пересоздать таблицу или вручную добавить новые столбцы в сводную таблицу.

Второй случай: был указан параметр accept. Например:

create table xpivet2 (
name varchar(12) not null,
dog int not null default 0 flag=1,
cat int not null default 0 flag=1)
engine=connect table_type=pivot tabname=pet
option_list='PivotCol=race,groupby=1,Accept=1';

Ошибка не будет поднята, и несоответствующие значения будут проигнорированы. Эта таблица будет отображена как:

Имя Собака Кот
John 2 0
Bill 0 1
Mary 1 1
Lisbeth 0 0
Kevin 0 2
Donald 1 0

Третий случай: был указан столбец «dump» со значением флага, равным 2. Все несоответствующие значения будут добавлены в этот столбец. Например:

create table xpivet (
name varchar(12) not null,
dog int not null default 0 flag=1,
cat int not null default 0 flag=1,
other int not null default 0 flag=2)
engine=connect table_type=pivot tabname=pet
option_list='PivotCol=race,groupby=1';

Эта таблица будет отображена как:

Имя Собака Кот Другое
John 2 0 0
Bill 0 1 0
Mary 1 1 0
Lisbeth 0 0 2
Kevin 0 2 6
Donald 1 0 3

Полезно предоставить такой столбец «dump», если исходная таблица подвержена вставке новых строк, которые могут иметь значение для столбца сводки, которое отсутствовало при создании сводной таблицы.

Преобразование больших исходных таблиц

Это иногда может быть рискованно. Если столбец сводки содержит слишком много различных значений, результирующая таблица может иметь слишком много столбцов. Во всех случаях, процесс поиска уникальных значений при создании таблицы или выполнении группировки при её использовании может быть очень долгим и иногда может завершиться неудачно из-за недостатка памяти.

Ограничения с помощью условия where должны применяться к исходной таблице при создании сводной таблицы, а не к самой сводной таблице. Это можно сделать, создав промежуточную таблицу или используя в качестве источника представление или параметр srcdef.

Все сводные таблицы являются только для чтения.

Содержимое, воспроизведённое на этом сайте, является собственностью соответствующих владельцев, и это содержимое не предварительно проверяется MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают точки зрения MariaDB или любой другой стороны.

© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/connect-pivot-table-type/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API