SELECT
Содержание раздела
- Синтаксис
- Ограничения
- Примеры
- Звездочка и WHERE
- DATASOURCE_TYPE
- GROUP BY, ORDER BY и LIMIT
- ESTIMATE_ONLY
- COLLATE
- LISTAGG
- OFFSET
- ORDER BY, LIMIT и OFFSET
- FOR SYSTEM_TIME AS OF DELTA_NUM
- Соединение таблиц из разных логических БД
- Соединение изменений из разных дельт
- Запрос из standalone-таблицы
- Соединение standalone-таблицы и логической таблицы
Запрос возвращает данные из следующих сущностей и их соединений:
Синтаксис чтения из standalone-таблицы подразумевает использование внешней readable-таблицы, которая указывает на нужную standalone-таблицу.
Запросы к логическим таблицам и представлениям по умолчанию возвращают данные, актуальные на текущий момент. Чтобы выбрать срез данных на определенный момент времени, укажите ключевое слово FOR SYSTEM_TIME с нужным значением. Для standalone-таблиц ключевое слово недоступно: запросы к таким таблицам всегда возвращают текущее состояние данных.
Запрос SELECT
обрабатывается в порядке, описанном в разделе Порядок обработки запросов на чтение данных.
В ответе возвращается:
- объект ResultSet c выбранными записями или информацией о запросе при успешном выполнении запроса;
- исключение при неуспешном выполнении запроса.
Запрос можно использовать для получения информации о самом запросе, а также как подзапрос в других запросах:
- на выгрузку данных,
- на создание или обновление логического представления,
- на создание материализованного представления,
- на вставку данных из другой сущности.
Синтаксис
SELECT column_list
FROM [db_name.]entity_name
[FOR SYSTEM_TIME time_expression [AS alias_name]]
[DATASOURCE_TYPE = datasource_alias]
[ESTIMATE_ONLY]
Параметры:
column_list
-
Список выбираемых столбцов таблицы или представления. Можно указывать символ
*
для выбора всех столбцов. db_name
-
Имя логической базы данных, из которой выбираются данные. Опционально, если выбрана логическая БД, используемая по умолчанию.
entity_name
-
Имя таблицы или представления, из которого выбираются данные.
time_expression
-
Выражение, задающее момент или период времени, за который выбираются данные или изменения данных. Синтаксис см. ниже.
alias_name
-
Псевдоним таблицы или представления. Может включать латинские буквы, цифры и символы подчеркивания.
datasource_alias
-
Системный псевдоним СУБД хранилища, из которой выбираются данные. Возможные значения:
'adb'
,'adqm'
,'adg'
,'adp'
.
В запросах можно указывать:
- ключевые слова, перечисленные в секции Поддерживаемые ключевые слова,
- функции, перечисленные в разделе Поддержка SQL,
- псевдонимы для имен таблиц, представлений и столбцов.
Некоторые агрегатные функции и типы соединений недоступны для исполнения в определенных СУБД хранилища. Список доступных возможностей см. в разделе Поддержка SQL.
Поддерживаемые ключевые слова
В запросе можно использовать следующие ключевые слова, которые должны быть указаны в порядке их перечисления:
LISTAGG
— объединяет значения в строку. Описание и синтаксис см. в секции Ключевое слово LISTAGG;FOR SYSTEM_TIME
— задает момент времени или период, за который выбираются данные или изменения данных. Поддерживается для логических таблиц, логических и материализованных представлений. Описание и синтаксис см. в секции Ключевое слово FOR SYSTEM_TIME;JOIN ON
— соединяет данные нескольких таблиц и (или) представлений из одной или нескольких логических БД. Возможные значения см. в секции Поддерживаемые типы соединений;WHERE
— задает условия выбора данных. Условия в запросах к ADG могут включать ключевое слово COLLATE;GROUP BY
— группирует данные;HAVING
— задает условия выбора сгруппированных данных;ORDER BY
— сортирует данные;LIMIT
илиFETCH NEXT <N> ROWS ONLY
— ограничивает количество возвращаемых строк;OFFSET
— пропускает указанное количество строк в результате запроса. Описание и синтаксис см. в секции Ключевое слово OFFSET;DATASOURCE_TYPE
— задает СУБД хранилища, из которой выбираются данные. Поддерживается для логических таблиц, логических и материализованных представлений;ESTIMATE_ONLY
— включает режим получения информации о запросе, а не самих данных. Описание см. в секции Ключевое слово ESTIMATE_ONLY.
Ключевое слово LISTAGG
Ключевое слово объединяет значения в одну строку, перечисляя их через заданный разделитель. После последнего значения разделитель не добавляется. Строки со значением NULL
пропускаются, и соответствующий разделитель не добавляется. Примеры запросов см. ниже.
По умолчанию результаты не сортируются, для их сортировки нужно указать условие сортировки.
Ключевое слово доступно в запросах к ADB и ADP.
Если в инсталляции есть другие СУБД, в запросах со LISTAGG
указывайте выражение DATASOURCE_TYPE = 'adb'
или DATASOURCE_TYPE = 'adp'
для выбора ADB или ADP в качестве источника данных.
Синтаксис:
LISTAGG (expression, separator) [WITHIN GROUP (ORDER BY <order_by_expression_list> [ ASC | DESC ])]
Параметры:
expression
— выражение для выбора значений. Может иметь любой тип. Перед объединением все значения приводятся системой к типу VARCHAR;separator
— разделитель между значениями. Может быть любым выражением, кроме символа перевода строки;order_by_expression_list
— выражение для сортировки результатов. По умолчанию результаты сортируются в порядке ASC (по возрастанию).
Ключевое слово FOR SYSTEM_TIME
Ключевое слово FOR SYSTEM_TIME
задает момент, по состоянию на который запрашиваются данные, или период (диапазон дельт), за который запрашиваются изменения. Возможные значения см. в секции ниже.
Ключевое слово относится к логической таблице, логическому представлению или материализованному представлению, после имени которого оно следует. Если в запросе соединяется несколько логических сущностей, для каждой из них можно указать свое ключевое слово FOR SYSTEM_TIME
. Значения ключевых слов FOR SYSTEM_TIME
у сущностей в запросе могут быть одинаковыми или разными (см. пример ниже).
Наличие и значение ключевого слова FOR SYSTEM_TIME
в запросах к материализованным представлениям влияют на порядок маршрутизации запросов.
Ключевое слово недоступно в запросах к standalone-таблицам.
Если указан номер несуществующей дельты, в ответе возвращается ошибка с пояснением, что дельта с таким номером не существует или диапазон дельт некорректный.
Для логического представления, построенного на основе таблиц из разных логических баз данных, данные из всех таблиц выбираются за один и тот же момент или период времени. Момент и период времени определяются по дельтам той логической базы данных, которой принадлежит представление.
Если ключевое слово не указано, из логических таблиц и логических представлений выбираются данные, актуальные на последнюю закрытую дельту, из материализованного представления — данные, актуальные на момент последней синхронизации этого представления.
Возможные значения FOR SYSTEM_TIME
FOR SYSTEM_TIME AS OF 'YYYY-MM-DD hh:mm:ss'
-
Запрос данных, актуальных на указанную дату и время. Возможные форматы даты и времени см. в разделе Форматы даты и времени в запросах.
FOR SYSTEM_TIME AS OF DELTA_NUM delta_num
-
Запрос данных, актуальных на дату и время закрытия дельты с номером
delta_num
. FOR SYSTEM_TIME AS OF LATEST_UNCOMMITTED_DELTA
-
Запрос данных на текущий момент, включая данные, загруженные в горячей дельте. По горячей дельте возвращаются записи, загруженные в рамках непрерывного диапазона завершенных операций записи (см. параметры
cn_from
иcn_to
в разделе GET_DELTA_HOT). FOR SYSTEM_TIME STARTED IN (delta_num1, delta_num2)
-
Запрос данных, добавленных или измененных в период между дельтой
delta_num1
и дельтойdelta_num2
(включая граничные дельты).
Возвращается разница в состоянии данных между дельтами, а не весь набор изменений данных за это время. Например, если у клиента менялся номер телефона в дельтах 3 и 6, то при запросе изменений по дельтам[3, 6]
для этого клиента вернется одна запись с итоговым номером телефона. FOR SYSTEM_TIME FINISHED IN (delta_num1, delta_num2)
-
Запрос данных, удаленных в период между дельтой
delta_num1
и дельтойdelta_num2
(включая граничные дельты).
Возвращается разница в состоянии данных между дельтами, а не весь набор изменений данных за это время. Например, если информация о договоре была добавлена в дельте 1 и удалена в дельте 2, то при запросе удаленных записей по дельтам[1, 2]
в ответе не будет записей по этому договору.
Доступность значений FOR SYSTEM_TIME
В таблице ниже описана доступность значений FOR SYSTEM_TIME
в SELECT-запросах к таблицам и представлениям.
Выражение | Логические таблицы | Логические представления* | Мат. представления* |
---|---|---|---|
FOR SYSTEM_TIME AS OF 'YYYY-MM-DD hh:mm:ss' | + | + | + |
FOR SYSTEM_TIME AS OF DELTA_NUM delta_num | + | + | + |
FOR SYSTEM_TIME AS OF LATEST_UNCOMMITTED_DELTA | + | – | – |
FOR SYSTEM_TIME STARTED IN (delta_num1, delta_num2) | + | + Если запрос предназначен для ADP, ADB или ADG и в представлении не используется ORDER BY | + Если в представлении есть обе дельты диапазона |
FOR SYSTEM_TIME FINISHED IN (delta_num1, delta_num2) | + | + Если запрос предназначен для ADP, ADB или ADG и в представлении не используется ORDER BY | + Если в представлении есть обе дельты диапазона |
* Имеется в виду доступность выражения в SELECT-запросах к представлениям. В SELECT-подзапросах в составе запросов на создание и изменение представлений ключевое слово FOR SYSTEM_TIME
недоступно в любом виде.
Поддерживаемые типы соединений
Поддерживаются следующие типы соединений:
[INNER] JOIN
— внутреннее соединение,NATURAL JOIN
— внутреннее соединение по всем столбцам с одинаковыми именами, ключи соединения не указываются,LEFT [OUTER] JOIN
— левое внешнее соединение,RIGHT [OUTER] JOIN
— правое внешнее соединение,FULL [OUTER] JOIN
— полное внешнее соединение,CROSS JOIN
— декартово произведение таблиц или представлений, ключи соединения не указываются.
Данные соединяемых сущностей должны храниться хотя бы в одной общей СУБД хранилища, иначе соединение невозможно.
Например, можно соединить логическую таблицу, размещенную в ADB, с таблицей, размещенной в ADB и ADG (соединение выполняется в ADB), но невозможно соединить таблицу, размещенную в ADB, с таблицей, размещенной в ADP.
Ключевое слово COLLATE
Ключевое слово COLLATE
позволяет задать правило сопоставления символьных строк, например, приравнять строки в верхнем и нижнем регистрах. Ключевое слово доступно в блоке WHERE
(см. пример ниже).
Подробнее о правилах сопоставления символьных строк в ADG см. в документации Tarantool.
Ключевое слово COLLATE
доступно в запросах к ADG.
Если в инсталляции есть другие СУБД, в запросах с COLLATE
указывайте выражение DATASOURCE_TYPE = 'adg'
для выбора ADG в качестве источника данных.
Ключевое слово OFFSET
Ключевое слово OFFSET
позволяет пропустить первые несколько строк результата и выбрать только последующие строки. Примеры запросов см. ниже.
В качестве значения ключевого слова можно указать любое неотрицательное целое число, начиная с нуля, или переменную. Если для OFFSET
указано значение 0, то пропускается 0 строк, что равносильно запросу без OFFSET
.
Запросы с OFFSET
без ограничения количества строк не поддерживаются. То есть, если ключевое слово OFFSET
указано в запросе, то перед ним должно быть ключевое слово LIMIT <N>
или FETCH NEXT <N> ROWS ONLY
. Обратного ограничения нет: ключевые слова LIMIT <N>
и FETCH NEXT <N> ROWS ONLY
можно использовать без OFFSET
.
Рекомендуется сочетать OFFSET
с ключевым словом ORDER BY
для получения упорядоченного набора строк. Ключевое слово ORDER BY
необязательно, однако без него запрос с OFFSET
возвращает неупорядоченный и потому непредсказуемый набор строк.
Таким образом, для ключевого слова OFFSET
поддерживается следующий синтаксис:
[ ORDER BY <column_name> ]
{ LIMIT <value_1> | FETCH NEXT <value_1> ROWS ONLY }
OFFSET <value_2> [ ROW | ROWS ]
Ключевое слово ESTIMATE_ONLY
Ключевое слово ESTIMATE_ONLY
позволяет запросить информацию о выполнении запроса к данным, а не сами данные (см. пример ниже).
Если ключевое слово указано, запрос возвращает следующую информацию:
- имя СУБД хранилища, в которой предполагается выполнение запроса;
- план выполнения запроса (для ADB и ADP) — результат выполнения команды EXPLAIN в СУБД хранилища. Подробнее о команде EXPLAIN в ADB см. в документации Greenplum, о команде в ADP — в документации PostgreSQL;
- обогащенный запрос — запрос, подготовленный системой на основе исходного запроса с учетом специфики СУБД хранилища.
В ответе возвращается объект ResultSet с одной строкой, содержащей JSON-строку в следующем формате:
{
"plugin": "<имя_СУБД>",
"estimation": <план_выполнения_запроса>,
"query": <обогащенный_запрос>
}
Ниже показан пример JSON-строки, полученной из ADB. Для наглядности пример представлен в виде дерева, а не плоской строки.
{
"plugin": "ADB",
"estimation": [
{
"Plan": {
"Node Type": "Gather Motion",
"Senders": 4,
"Receivers": 1,
"Slice": 1,
"Segments": 4,
"Gang Type": "primary reader",
"Startup Cost": 0.00,
"Total Cost": 433.70,
"Plan Rows": 50000,
"Plan Width": 8,
"Plans": [
{
"Node Type": "Seq Scan",
"Parent Relationship": "Outer",
"Slice": 1,
"Segments": 4,
"Gang Type": "primary reader",
"Relation Name": "sales_actual",
"Alias": "sales_actual",
"Startup Cost": 0.00,
"Total Cost": 432.18,
"Plan Rows": 50000,
"Plan Width": 8
}
]
},
"Settings": {
"Optimizer": "Pivotal Optimizer (GPORCA)"
}
}
],
"query": "SELECT * FROM (SELECT id FROM marketing.sales_actual WHERE sys_from <= 98 AND COALESCE(sys_to, 9223372036854775807) >= 98)"
}
Ниже показан пример JSON-строки, полученной из ADP. Для наглядности пример представлен в виде дерева, а не плоской строки.
{
"plugin": "ADP",
"estimation": [
{
"Plan": {
"Node Type": "Seq Scan",
"Parallel Aware": false,
"Relation Name": "sales_actual",
"Alias": "sales_actual",
"Startup Cost": 0.00,
"Total Cost": 18.80,
"Plan Rows": 880,
"Plan Width": 64
}
}
],
"query": "SELECT * FROM (SELECT id FROM marketing.sales_actual WHERE sys_from <= 98 AND COALESCE(sys_to, 9223372036854775807) >= 98)"
}
Ограничения
Ограничения сущностей
- В запросе можно обращаться либо к логической БД, либо к сервисной БД (см. SELECT FROM INFORMATION_SCHEMA), но не к обеим одновременно.
Ограничения ключевых слов
- Ключевое слово
LISTAGG
недоступно в запросах к ADQM и ADG. - Ключевое слово
COLLATE
недоступно в запросах к ADB, ADP и ADQM. - Ключевое слово
ESTIMATE_ONLY
не возвращает план выполнения запроса для ADQM и ADG. - Ключевое слово
OFFSET
без ограничения количества строк не поддерживается. FOR SYSTEM_TIME
:- Ключевое слово
FOR SYSTEM_TIME
, указанное для standalone-таблиц, игнорируется. - Выражение
FOR SYSTEM_TIME AS OF LATEST_UNCOMMITTED_DELTA
недоступно в запросах к логическим и материализованным представлениям. - Выражения
FOR SYSTEM_TIME STARTED IN
иFOR SYSTEM_TIME FINISHED IN
недоступны в запросе к логическому представлению, если запрос предназначен для ADQM или в представлении используется ключевое словоORDER BY
.
- Ключевое слово
- Ключевое слово
ORDER BY
недоступно в SELECT-подзапросе в составе CREATE MATERIALIZED VIEW.
Ограничения соединений
- Не поддерживается соединение сущностей, данные которых размещены в разных СУБД хранилища без какой-либо общей СУБД.
- Если ключами соединения в запросе выступают поля типа Nullable, то строки, где хотя бы один из ключей имеет значение
NULL
, не соединяются.
Примеры
Звездочка и WHERE
Запрос с неявным указанием столбцов и ключевым словом WHERE
:
SELECT * FROM marketing.sales
WHERE store_id = 1234
DATASOURCE_TYPE
Запрос с перечислением столбцов и выбором данных из определенной СУБД хранилища (ADQM):
SELECT sold.store_id, sold.product_amount
FROM marketing.stores_by_sold_products AS sold
DATASOURCE_TYPE = 'adqm'
GROUP BY, ORDER BY и LIMIT
Запрос с агрегацией, группировкой и сортировкой данных, а также выбором первых 20 строк:
SELECT s.store_id, SUM(s.product_units) AS product_amount
FROM marketing.sales AS s
GROUP BY (s.store_id)
ORDER BY product_amount DESC
LIMIT 20
ESTIMATE_ONLY
Запрос на получение информации о запросе:
SELECT s.store_id, SUM(s.product_units) AS product_amount
FROM marketing.sales AS s
GROUP BY (s.store_id)
ORDER BY product_amount DESC
ESTIMATE_ONLY
Описание ключевого слова см. в секции Ключевое слово ESTIMATE_ONLY.
COLLATE
Запрос строк с указанными значениями без учета регистра:
SELECT * from marketing.sales
WHERE product_code = 'ABC1234' AND product_code <> 'abc4567' COLLATE 'unicode_ci'
DATASOURCE_TYPE = 'adg'
Описание ключевого слова см. в секции Ключевое слово COLLATE.
LISTAGG
Запрос плоского списка
Запрос списка ФИО клиентов с их датой рождения:
SELECT LISTAGG (last_name || ' ' || first_name || ' ' || patronymic_name || ' ' || birth_date , ', ')
WITHIN GROUP (ORDER BY last_name, first_name, patronymic_name DESC)
FROM marketing.clients datasource_type = 'adp'
Ниже на рисунке показан пример ответа на такой запрос:
Запрос списка по группам
Запрос списка адресов магазинов с группировкой по городам:
SELECT region, LISTAGG (address, '; ')
WITHIN GROUP (ORDER BY address)
FROM marketing.stores
GROUP BY region
ORDER BY region ASC
DATASOURCE_TYPE = 'adb'
Ниже на рисунке показан пример ответа на такой запрос:
Описание ключевого слова см. в секции Ключевое слово LISTAGG.
OFFSET
Запрос 20 строк, начиная с десятой:
SELECT * from marketing.sales FETCH NEXT 20 ROWS ONLY OFFSET 9
Описание ключевого слова см. в секции Ключевое слово OFFSET.
ORDER BY, LIMIT и OFFSET
Запрос 20 строк, упорядоченных по значению id
и выбираемых начиная с десятой строки результата:
SELECT * from marketing.sales ORDER BY id LIMIT 20 OFFSET 9
Такое сочетание ключевых слов позволяет выбирать данные порциями с сохранением их порядка.
FOR SYSTEM_TIME AS OF DELTA_NUM
Запрос записей, актуальных на момент закрытия дельты с номером 9, из материализованного представления:
SELECT * FROM marketing.sales_and_stores FOR SYSTEM_TIME AS OF DELTA_NUM 9
Описание ключевого слова см. в секции Ключевое слово FOR SYSTEM_TIME.
Соединение таблиц из разных логических БД
Запрос с соединением данных логических таблиц из двух разных логических БД:
SELECT
st.id,
st.category,
s.product_code
FROM marketing.stores AS st
INNER JOIN marketing_new.sales AS s
ON st.id = s.store_id
О возможных типах соединений см. в секции Поддерживаемые типы соединений.
Соединение изменений из разных дельт
Запрос с соединением записей логической таблицы, добавленных и измененных в двух различных диапазонах дельт:
SELECT st.id, st.category, s.product_code
FROM marketing.stores FOR SYSTEM_TIME STARTED IN(0,7) AS st
INNER JOIN marketing.sales FOR SYSTEM_TIME STARTED IN(0,1) AS s
ON st.id = s.store_id
О возможных типах соединений см. в секции Поддерживаемые типы соединений.
Запрос из standalone-таблицы
-- запрос данных из standalone-таблицы, на которую указывает внешняя readable-таблица payments_ext_read_adg
SELECT p.agreement_id, p.code, SUM(p.amount) AS amount, p.currency_code
FROM marketing.payments_ext_read_adg AS p
GROUP BY p.agreement_id, p.code, p.currency_code
Соединение standalone-таблицы и логической таблицы
-- запрос данных из логической таблицы clients и standalone-таблицы, на которую указывает
-- внешняя readable-таблица agreements_ext_read_adp
SELECT a.id, a.client_id, c.last_name, c.first_name, c.patronymic_name
FROM marketing.agreements_ext_read_adp AS a
LEFT JOIN marketing.clients FOR SYSTEM_TIME AS OF delta_num 9 AS c
ON a.client_id = c.id