Перейти к основному содержимому
Перейти к основному содержимому

Синтаксис

В этом разделе мы рассмотрим синтаксис SQL ClickHouse. ClickHouse использует синтаксис, основанный на SQL, но предлагает ряд расширений и оптимизаций.

Парсинг запросов

В ClickHouse есть два типа парсеров:

  • Полный SQL-парсер (рекурсивный спусковой парсер).
  • Парсер форматов данных (быстрый стрим-парсер).

Полный SQL-парсер используется во всех случаях, кроме запроса INSERT, который использует оба парсера.

Давайте рассмотрим запрос ниже:

Как уже упоминалось, запрос INSERT использует оба парсера. Фрагмент INSERT INTO t VALUES парсится полным парсером, а данные (1, 'Hello, world'), (2, 'abc'), (3, 'def') парсится парсером форматов данных, или быстрым стрим-парсером.

Включение полного парсера

Вы также можете включить полный парсер для данных с помощью настройки input_format_values_interpret_expressions.

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

Данные могут быть в любом формате. Когда сервер получает запрос, он вычисляет не более чем max_query_size байт запроса в ОЗУ (по умолчанию 1 МБ), а остальная часть обрабатывается стрим-парсером. Это делается для избежания проблем с большими запросами INSERT, что является рекомендуемым способом вставки ваших данных в ClickHouse.

При использовании формата Values в запросе INSERT может показаться, что данные парсятся так же, как для выражений в запросе SELECT, однако это не так. Формат Values гораздо более ограничен.

Остальная часть этого раздела охватывает полный парсер.

примечание

Для получения дополнительной информации о парсерах форматов смотрите раздел Форматы.

Пробелы

  • Между синтаксическими конструкциями может быть любое количество символов пробела (включая начало и конец запроса).
  • Символы пробела включают пробел, табуляцию, перевод строки, CR и символ перевода страницы.

Комментарии

ClickHouse поддерживает как комментарии в стиле SQL, так и комментарии в стиле C:

  • Комментарии в стиле SQL начинаются с --, #! или # и продолжаются до конца строки. Пробел после -- и #! можно опустить.
  • Комментарии в стиле C охватывают от /* до */ и могут быть многострочными. Пробелы также не обязательны.

Ключевые слова

Ключевые слова в ClickHouse могут быть как чувствительными к регистру, так и неличной чувствительными к регистру в зависимости от контекста.

Ключевые слова являются неличной чувствительными к регистру, когда они соответствуют:

  • Стандарту SQL. Например, SELECT, select и SeLeCt все допустимы.
  • Реализациям в некоторых популярных СУБД (MySQL или Postgres). Например, DateTime такое же, как и datetime.
примечание

Вы можете проверить, является ли имя типа данных чувствительным к регистру в таблице system.data_type_families.

В отличие от стандартного SQL, все остальные ключевые слова (включая имена функций) являются чувствительными к регистру.

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

Например, следующий запрос действителен, если таблица table_name имеет колонку с именем "FROM":

Идентификаторы

Идентификаторы это:

Идентификаторы могут быть с кавычками или без, хотя последние предпочитаются.

Не заключенные в кавычки идентификаторы должны соответствовать регулярному выражению ^[a-zA-Z_][0-9a-zA-Z_]*$ и не могут быть равны ключевым словам. См. таблицу ниже для примеров действительных и недействительных идентификаторов:

Действительные идентификаторыНедействительные идентификаторы
xyz, _internal, Id_with_underscores_123_1x, [email protected], äußerst_schön

Если вы хотите использовать идентификаторы такие же, как ключевые слова, или хотите использовать другие символы в идентификаторах, заключите их в двойные кавычки или обратные кавычки, например, "id", `id`.

примечание

Тем же правилам экранирования, которые применяются к идентификаторам с кавычками, также подлежат строковые литералы. Смотрите Строка для более подробной информации.

Литералы

В ClickHouse литерал это значение, которое напрямую представлено в запросе. Другими словами, это фиксированное значение, которое не меняется во время выполнения запроса.

Литералы могут быть:

Мы рассматриваем каждый из этих более подробно в следующих разделах.

Строка

Строковые литералы должны быть заключены в одинарные кавычки. Двойные кавычки не поддерживаются.

Экранирование происходит следующим образом:

  • с помощью предшествующей одинарной кавычки, где символ одинарной кавычки ' (и только этот символ) может быть экранирован как '', или
  • с использованием предшествующего обратного слэша с помощью следующих поддерживаемых последовательностей экранирования, перечисленных в таблице ниже.
примечание

Обратный слэш теряет свое специальное значение, т.е. он интерпретируется буквально, если он предшествует символам, отличным от перечисленных ниже.

Поддерживаемое экранированиеОписание
\xHHСпецификация 8-битного символа, за которой следует любое количество шестнадцатеричных цифр (H).
\Nзарезервировано, ничего не делает (например, SELECT 'a\Nb' возвращает ab)
\aоповещение
\bвозврат курсора
\eсимвол экранирования
\fперевод страницы
\nперевод строки
\rвозврат каретки
\tгоризонтальная табуляция
\vвертикальная табуляция
\0нулевой символ
\\обратный слэш
\' (или '')одинарная кавычка
\"двойная кавычка
`обратная кавычка
\/прямой слэш
\=знак равенства
ASCII управляющие символы (c <= 31)
примечание

В строковых литералах необходимо экранировать как минимум ' и \ с использованием кодов экранирования \' (или: '') и \\.

Числовой

Числовые литералы обрабатываются следующим образом:

  • Сначала как 64-битное знаковое число, с использованием функции strtoull.
  • Если не удалось, как 64-битное беззнаковое число, с использованием функции strtoll.
  • Если и это не удалось, как число с плавающей точкой с использованием функции strtod.
  • В противном случае возвращается ошибка.

Литералы значений приводятся к наименьшему типу, в который помещается значение. Например:

  • 1 интерпретируется как UInt8
  • 256 интерпретируется как UInt16.

Для получения дополнительной информации см. Типы данных.

Подчеркивания _ внутри числовых литералов игнорируются и могут использоваться для улучшения читаемости.

Поддерживаются следующие числовые литералы:

Числовой литералПримеры
Целые числа1, 10_000_000, 18446744073709551615, 01
Десятичные числа0.1
Научная нотация1e100, -1e-100
Числа с плавающей точкой123.456, inf, nan
Шестнадцатеричные0xc0fe
Шестнадцатеричная строка, совместимая со стандартом SQLx'c0fe'
Двоичные0b1101
Двоичная строка, совместимая со стандартом SQLb'1101'
примечание

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

Составной

Массивы создаются с помощью квадратных скобок [1, 2, 3]. Кортежи создаются с помощью круглых скобок (1, 'Hello, world!', 2). Технически это не литералы, а выражения с оператором создания массива и оператором создания кортежа соответственно. Массив должен состоять как минимум из одного элемента, а кортеж должен содержать как минимум два элемента.

примечание

Существует отдельный случай, когда кортежи появляются в клаузе IN в запросе SELECT. Результаты запроса могут включать кортежи, но кортежи не могут быть сохранены в базу данных (за исключением таблиц, использующих движок Memory).

NULL

NULL используется для указания того, что значение отсутствует. Чтобы сохранить NULL в поле таблицы, оно должно быть типа Nullable.

примечание

Следующее следует отметить для NULL:

  • В зависимости от формата данных (входящего или выходящего), NULL может иметь различное представление. Для получения дополнительной информации смотрите форматы данных.
  • Обработка NULL nuanced. Например, если хотя бы один из аргументов операции сравнения равен NULL, результат этой операции также равен NULL. То же самое относится к умножению, сложению и другим операциям. Мы рекомендуем ознакомиться с документацией по каждой операции.
  • В запросах вы можете проверить NULL с помощью операторов IS NULL и IS NOT NULL и связанных функций isNull и isNotNull.

Heredoc

Heredoc — это способ определения строки (часто многострочной), при этом сохраняя исходное форматирование. Heredoc определяется как пользовательский строковый литерал, помещенный между двумя символами $.

Например:

примечание
  • Значение между двумя heredocs обрабатывается "как есть".
подсказка
  • Вы можете использовать heredoc для внедрения фрагментов SQL, HTML или XML кода и т.д.

Определение и использование параметров запроса

Параметры запроса позволяют вам писать универсальные запросы, содержащие абстрактные заполнители вместо конкретных идентификаторов. Когда запрос с параметрами запроса выполняется, все заполнители разрешаются и заменяются фактическими значениями параметров запроса.

Существует два способа определения параметра запроса:

  • SET param_<name>=<value>
  • --param_<name>='<value>'

При использовании второго варианта он передается как аргумент для clickhouse-client в командной строке, где:

  • <name> — это имя параметра запроса.
  • <value> — его значение.

Параметр запроса может ссылаться на запрос с использованием {<name>: <datatype>}, где <name> — это имя параметра запроса, а <datatype> — это тип данных, в который он преобразуется.

Пример с командой SET

Например, следующий SQL определяет параметры с именами a, b, c и d - каждый с разным типом данных:

Пример с clickhouse-client

Если вы используете clickhouse-client, параметры указываются как --param_name=value. Например, следующий параметр имеет имя message и его извлекают как String:

Если параметр запроса представляет собой имя базы данных, таблицы, функции или другого идентификатора, используйте Identifier как его тип. Например, следующий запрос возвращает строки из таблицы с именем uk_price_paid:

примечание

Параметры запроса не являются общими текстовыми заменами, которые могут использоваться в произвольных местах в произвольных SQL-запросах. Они в первую очередь предназначены для работы в SELECT операторах вместо идентификаторов или литералов.

Функции

Вызовы функций записываются как идентификатор с списком аргументов (возможно, пустым) в круглых скобках. В отличие от стандартного SQL, скобки обязательны, даже для пустого списка аргументов. Например:

Существуют также:

Некоторые агрегатные функции могут содержать два списка аргументов в скобках. Например:

Эти агрегатные функции называются "параметрическими" функциями, и аргументы в первом списке называются "параметрами".

примечание

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

Операторы

Операторы преобразуются в соответствующие функции во время парсинга запроса, учитывая их приоритет и ассоциативность.

Например, выражение

преобразуется в

Типы данных и движки таблиц базы данных

Типы данных и движки таблиц в запросе CREATE записываются так же, как идентификаторы или функции. Другими словами, они могут содержать аргументы в скобках, а могут и не содержать.

Для получения дополнительной информации смотрите разделы:

Выражения

Выражение может быть любым из следующих:

  • функцией
  • идентификатором
  • литералом
  • применением оператора
  • выражением в скобках
  • подзапросом
  • или звездочкой.

Оно также может содержать псевдоним.

Список выражений — это одно или несколько выражений, разделенных запятыми. Функции и операторы, в свою очередь, могут иметь выражения в качестве аргументов.

Псевдонимы выражений

Псевдоним — это имя, определенное пользователем для выражения в запросе.

Части синтаксиса выше объяснены ниже.

Часть синтаксисаОписаниеПримерЗаметки
ASКлючевое слово для определения псевдонимов. Вы можете определить псевдоним для имени таблицы или имени колонки в операторе SELECT, не используя ключевое слово AS.SELECT table_name_alias.column_name FROM table_name table_name_alias.В функции CAST ключевое слово AS имеет другое значение. См. описание функции.
exprЛюбое выражение, поддерживаемое ClickHouse.SELECT column_name * 2 AS double FROM some_table
aliasИмя для expr. Псевдонимы должны соответствовать синтаксису идентификаторов.SELECT "table t".column_name FROM table_name AS "table t".

Заметки по использованию

  • Псевдонимы глобальны для запроса или подзапроса, и вы можете определить псевдоним в любой части запроса для любого выражения. Например:
  • Псевдонимы не видны в подзапросах и между подзапросами. Например, при выполнении следующего запроса ClickHouse генерирует исключение Неизвестный идентификатор: num:
  • Если псевдоним определен для столбцов результата в операторе SELECT подзапроса, эти столбцы видны во внешнем запросе. Например:
  • Будьте осторожны с псевдонимами, которые совпадают с именами колонок или таблиц. Рассмотрим следующий пример:

В приведенном примере мы объявили таблицу t с колонкой b. Затем, при выборке данных, мы определили псевдоним sum(b) AS b. Поскольку псевдонимы глобальны, ClickHouse подменил литерал b в выражении argMax(a, b) на выражение sum(b). Эта подстановка вызвала исключение.

примечание

Вы можете изменить это поведение по умолчанию, установив prefer_column_name_to_alias в 1.

Звездочка

В запросе SELECT звездочка может заменить выражение. Для получения дополнительной информации смотрите раздел SELECT.