Из Википедии, бесплатной энциклопедии
  (Перенаправлено из SQL-запроса )
Перейти к навигации Перейти к поиску

Оператор SQL SELECT возвращает результирующий набор записей из одной или нескольких таблиц . [1] [2]

A Выберите оператор получает ноль или несколько строк из одной или нескольких таблиц базы данных или базы данных взглядов . В большинстве приложений SELECTэто наиболее часто используемая команда языка обработки данных (DML). Поскольку SQL является декларативным языком программирования , в SELECTзапросах указывается набор результатов, но не указывается, как его вычислять. База данных переводит запрос в « план запроса », который может варьироваться в зависимости от исполнения, версии базы данных и программного обеспечения базы данных. Эта функция называется « оптимизатором запросов », поскольку она отвечает за поиск наилучшего возможного плана выполнения запроса в рамках применимых ограничений.

Оператор SELECT имеет много необязательных предложений:

  • SELECTпредложение - это список столбцов или выражений SQL, которые должны быть возвращены запросом. Это примерно операция проекции реляционной алгебры .
  • ASнеобязательно предоставляет псевдоним для каждого столбца или выражения в SELECTпредложении. Это операция переименования реляционной алгебры .
  • FROMуказывает, из какой таблицы получить данные. [3]
  • WHEREуказывает, какие строки нужно получить. Это примерно операция выбора реляционной алгебры .
  • GROUP BYгруппирует строки, совместно использующие свойство, чтобы к каждой группе можно было применить агрегатную функцию .
  • HAVING выбирает среди групп, определенных предложением GROUP BY.
  • ORDER BY указывает, как упорядочить возвращенные строки.

Обзор [ править ]

SELECTэто самая распространенная операция в SQL, называемая «запрос». SELECTизвлекает данные из одной или нескольких таблиц или выражений. Стандартные SELECTоператоры не оказывают постоянного воздействия на базу данных. Некоторые нестандартные реализации SELECTмогут иметь постоянные эффекты, например SELECT INTOсинтаксис, представленный в некоторых базах данных. [4]

Запросы позволяют пользователю описывать требуемые данные, оставляя систему управления базами данных (СУБД) для выполнения планирования , оптимизации и выполнения физических операций, необходимых для получения желаемого результата.

Запрос включает список столбцов для включения в окончательный результат, обычно сразу после SELECTключевого слова. Звездочка (" *") может использоваться, чтобы указать, что запрос должен возвращать все столбцы запрошенных таблиц. SELECT- самый сложный оператор в SQL, с необязательными ключевыми словами и предложениями, которые включают:

  • Предложение FROM, которое указывает таблицы, из которых нужно получить данные. Предложение FROMможет включать необязательные JOINподпункты для определения правил объединения таблиц.
  • Предложение WHEREвключает предикат сравнения, который ограничивает строки, возвращаемые запросом. Предложение WHEREисключает все строки из набора результатов, в которых предикат сравнения не имеет значения True.
  • Предложение GROUP BYпроецирует строки, имеющие общие значения, в меньший набор строк. GROUP BYчасто используется в сочетании с функциями агрегирования SQL или для удаления повторяющихся строк из набора результатов. Предложение WHEREприменяется перед GROUP BYпредложением.
  • Предложение HAVINGвключает предикат, используемый для фильтрации строк, являющихся результатом GROUP BYпредложения. Поскольку он действует на результаты GROUP BYпредложения, в HAVINGпредикате предложения можно использовать функции агрегирования .
  • Предложение ORDER BYопределяет, какой столбец [столбцы] использовать для сортировки результирующих данных и в каком направлении их сортировать (по возрастанию или по убыванию). Без ORDER BYпредложения порядок строк, возвращаемых запросом SQL, не определен.
  • DISTINCTКлючевое слово [5] устраняет дубликаты данных. [6]

В следующем примере SELECTзапроса возвращается список дорогих книг. Запрос извлекает все строки из таблицы Book, в которой столбец цен содержит значение больше 100,00. Результат сортируется по заголовку в порядке возрастания . Звездочка (*) в списке выбора указывает, что все столбцы таблицы Book должны быть включены в набор результатов.

ВЫБЕРИТЕ  *  ИЗ  ЗАКАЗА,  ГДЕ  цена  >  100 . 00  ЗАКАЗАТЬ  ПО  заголовку ;

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

ВЫБЕРИТЕ  книгу . title  AS  Название ,  количество ( * )  AS  Авторы  ИЗ  книги  ПРИСОЕДИНЯЙТЕСЬ  Book_author  ON  Книга . isbn  =  Автор_книги . isbn  ГРУППА  ПО  Книга . название ;

Пример вывода может выглядеть следующим образом:

Название Авторы---------------------- -------Примеры SQL и руководство 4Радость SQL 1Введение в SQL 2Подводные камни SQL 1

При предварительном условии, что isbn является единственным общим именем столбца для двух таблиц и что столбец с именем title существует только в таблице Book , можно переписать приведенный выше запрос в следующей форме:

ВЫБРАТЬ  заголовок ,  количество ( * )  КАК  Авторы  ИЗ  книги  ЕСТЕСТВЕННОЕ  СОЕДИНЕНИЕ  Book_author  ГРУППА  ПО  заголовку ;

Однако многие поставщики [ количественной оценки ] либо не поддерживают этот подход, либо требуют определенных соглашений об именах столбцов для эффективной работы естественных объединений.

SQL включает в себя операторы и функции для вычисления значений по сохраненным значениям. SQL позволяет использовать выражения в списке выбора для проецирования данных, как в следующем примере, который возвращает список книг стоимостью более 100,00 с дополнительным столбцом sales_tax, содержащим сумму налога с продаж, рассчитанную по ставке 6% от цены .

ВЫБЕРИТЕ  isbn ,  название ,  цену ,  цену  *  0 . 06  AS  sales_tax  FROM  Книги  WHERE  цена  >  100 . 00  ЗАКАЗАТЬ  ПО  заголовку ;

Подзапросы [ править ]

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

ВЫБЕРИТЕ  isbn ,  название ,  цену  ИЗ  книги  ГДЕ  цена  <  ( ВЫБЕРИТЕ  СРЕДНЮЮ ( цену )  ИЗ  книги )  ЗАКАЗАТЬ  ПО  заголовку ;

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

С 1999 года стандарт SQL допускает именованные подзапросы, называемые общими табличными выражениями (названные и разработанные в честь реализации IBM DB2 версии 2; Oracle называет эти подзапросы факторингом ). CTE также могут быть рекурсивными , ссылаясь на самих себя; Результирующий механизм позволяет обходы дерева или графа (когда они представлены как отношения) и, в более общем смысле, вычисления фиксированных точек .

Производная таблица [ править ]

Производная таблица - это использование ссылки на подзапрос SQL в предложении FROM. По сути, производная таблица - это подзапрос, который можно выбрать или присоединить к нему. Функциональность производной таблицы позволяет пользователю ссылаться на подзапрос как на таблицу. Производная таблица также называется встроенным представлением или выбором из списка .

В следующем примере оператор SQL включает соединение исходной таблицы Books с производной таблицей «Sales». Эта производная таблица фиксирует связанную информацию о продажах книг с использованием номера ISBN для присоединения к таблице "Книги". В результате производная таблица предоставляет результирующий набор с дополнительными столбцами (количество проданных товаров и компания, которая продала книги):

ВЫБРАТЬ  b . isbn ,  б . название ,  б . цена ,  распродажа . items_sold ,  продажи . company_nm ИЗ  книги  b  JOIN  ( SELECT  SUM ( Items_Sold )  Items_Sold ,  Company_Nm ,  ISBN  FROM  Book_Sales  GROUP  BY  Company_Nm ,  ISBN )  sales  ON  sales . isbn  =  b . isbn

Примеры [ править ]

Для таблицы T запрос приведет к отображению всех элементов всех строк таблицы.SELECT * FROM T

В той же таблице запрос приведет к отображению элементов из столбца C1 всех строк таблицы. Это похоже на проекцию в реляционной алгебре , за исключением того, что в общем случае результат может содержать повторяющиеся строки. В некоторых терминах базы данных это также известно как вертикальное разделение, ограничивающее вывод запроса для просмотра только определенных полей или столбцов.SELECT C1 FROM T

В той же таблице запрос приведет к отображению всех элементов всех строк, в которых значение столбца C1 равно «1» - в терминах реляционной алгебры выбор будет выполнен из-за предложения WHERE. Это также известно как горизонтальное разделение, ограничивающее вывод строк по запросу в соответствии с заданными условиями.SELECT * FROM T WHERE C1 = 1

При наличии более чем одной таблицы набором результатов будет каждая комбинация строк. Таким образом, если две таблицы - это T1 и T2, результатом будет каждая комбинация строк T1 с каждой строкой T2. Например, если в T1 3 строки, а в T2 5 строк, то получится 15 строк.SELECT * FROM T1, T2

Хотя это и не является стандартом, большинство СУБД позволяет использовать предложение select без таблицы, делая вид, что используется воображаемая таблица с одной строкой. В основном это используется для выполнения вычислений, когда таблица не нужна.

Предложение SELECT определяет список свойств (столбцов) по имени или символ подстановки («*»), означающий «все свойства».

Ограничение строк результатов [ править ]

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

В ISO SQL: 2003 наборы результатов могут быть ограничены с помощью

  • курсоры , или
  • добавив оконную функцию SQL к оператору SELECT

ISO SQL: 2008 представил это FETCH FIRSTположение.

Согласно документации PostgreSQL v.9, функция окна SQL выполняет вычисление по набору строк таблицы, которые каким-то образом связаны с текущей строкой , аналогично агрегатным функциям. [7] Название напоминает оконные функции обработки сигналов . Вызов оконной функции всегда содержит предложение OVER .

ROW_NUMBER () оконная функция [ редактировать ]

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

SELECT  *  FROM (  SELECT ROW_NUMBER () OVER ( ORDER BY sort_key ASC ) AS row_number , columns FROM tablename ) AS foo WHERE row_number <= 10                

ROW_NUMBER может быть недетерминированным : если sort_key не уникален, каждый раз, когда вы запускаете запрос, можно получить разные номера строк, назначенные любым строкам, где sort_key одинаков. Когда sort_key уникален, каждая строка всегда получает уникальный номер строки.

Функция окна RANK () [ править ]

RANK() OVERФункция окна действует как ROW_NUMBER, но может вернуться более или менее п строк в случае условий галстуков, например , вернуть топ-10 самых молодых людей:

ВЫБОР  *  FROM  (  SELECT , RANK () OVER ( ORDER BY возрастной ASC ) А.С. ранжирования , person_id , PERSON_NAME , возраст ОТ человека ) КАК Foo ГДЕ ранжирования <= 10                  

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

Предложение FETCH FIRST [ править ]

Начиная с ISO SQL: 2008 пределы результатов можно указать, как в следующем примере, с помощью FETCH FIRSTпредложения.

ВЫБОР  *  ОТ  T  FETCH  первой  10  ROWS  ТОЛЬКО

Этот пункт в настоящее время поддерживается CA DATACOM / DB 11, IBM DB2, SAP SQL Anywhere, PostgreSQL, EffiProz, H2, HSQLDB версии 2.0, Oracle 12c и Mimer SQL .

Microsoft SQL Server 2008 и выше поддерживаетFETCH FIRST , но это считается частью ORDER BYпункта. В ORDER BY, OFFSETи FETCH FIRSTположение , все необходимые для этого использования.

ВЫБОР * ОТ T ORDER BY acolumn DESC OFFSET 0 ЧСТРОК FETCH ПЕРВЫЙ 10 ЧСТРОК ТОЛЬКО               

Нестандартный синтаксис [ править ]

Некоторые СУБД предлагают нестандартный синтаксис вместо стандартного синтаксиса SQL или в дополнение к нему. Ниже перечислены варианты простого запроса лимита для разных СУБД:

Пагинация строк [ править ]

Пагинация строк [9] - это подход, используемый для ограничения и отображения только части общих данных запроса в базе данных. Вместо одновременного отображения сотен или тысяч строк сервер запрашивает только одну страницу (ограниченный набор строк, в примере только 10 строк), и пользователь начинает навигацию, запрашивая следующую страницу, а затем следующую. , и так далее. Это очень полезно, особенно в веб-системах, где нет выделенного соединения между клиентом и сервером, поэтому клиенту не нужно ждать, чтобы прочитать и отобразить все строки сервера.

Данные в подходе разбивки на страницы [ править ]

  • {rows} = Количество строк на странице
  • {page_number} = Номер текущей страницы
  • {begin_base_0} = Номер строки - 1, с которой начинается страница = (номер_страницы-1) * строки

Простейший метод (но очень неэффективный) [ править ]

  1. Выбрать все строки из базы данных
  2. Прочитать все строки, но отправить для отображения только тогда, когда row_number прочитанных строк находится между {begin_base_0 + 1}и{begin_base_0 + rows}
Выбрать  *  из  { table },  упорядочить  по  { unique_key }

Другой простой метод (немного более эффективный, чем чтение всех строк) [ править ]

  1. Выберите все строки от начала таблицы до последней строки для отображения ( {begin_base_0 + rows})
  2. Прочитать {begin_base_0 + rows}строки, но отправить для отображения только тогда, когда row_number прочитанных строк больше, чем{begin_base_0}


Метод с позиционированием [ править ]

  1. Выберите {rows}для отображения только строки, начиная со следующей строки ( {begin_base_0 + 1})
  2. Чтение и отправка для отображения всех строк, прочитанных из базы данных


Метод с фильтром (более сложный, но необходимый для очень большого набора данных) [ править ]

  1. Выбирать только тогда {rows}строки с фильтром:
    1. Первая страница: выберите только первые {rows}строки, в зависимости от типа базы данных.
    2. Следующая страница: выберите только первые {rows}строки, в зависимости от типа базы данных, где {unique_key}больше чем {last_val}(значение {unique_key}последней строки на текущей странице)
    3. Предыдущая страница: отсортируйте данные в обратном порядке, выберите только первые {rows}строки, где {unique_key}меньше чем {first_val}(значение {unique_key}первой строки на текущей странице), и отсортируйте результат в правильном порядке.
  2. Чтение и отправка для отображения всех строк, прочитанных из базы данных

Иерархический запрос [ править ]

Некоторые базы данных предоставляют специальный синтаксис для иерархических данных .

Оконная функция в SQL: 2003 - это агрегатная функция, применяемая к разделу набора результатов.

Например,

сумма (население) ПРЕВЫШАЕТ (РАЗДЕЛЕНИЕ ПО ГОРОДАМ)

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

Разделы указываются с помощью предложения OVER , которое изменяет агрегат. Синтаксис:

<ЗАКРЫТЬ_КРЫТЬ> :: = ВЫШЕ ([РАЗДЕЛЕНИЕ ПО <expr>, ...] [ЗАКАЗАТЬ ПО <выражение>])

Предложение OVER может разбивать и упорядочивать набор результатов. Упорядочивание используется для функций, относящихся к порядку, таких как row_number.

Оценка запроса ANSI [ править ]

Обработка оператора SELECT в соответствии с ANSI SQL будет следующей: [10]

  1. выберите  g . * От  пользователей  у  внутренней  присоединиться к  группам  г  на  г . Userid  =  u . Идентификатор пользователя где  u . LastName  =  'Smith' и  u . FirstName  =  'Джон'
  2. оценивается предложение FROM, создается перекрестное соединение или декартово произведение для первых двух таблиц в предложении FROM, в результате чего получается виртуальная таблица как Vtable1
  3. предложение ON оценивается для vtable1; только записи, которые соответствуют условию соединения g.Userid = u.Userid, вставляются в Vtable2
  4. Если указано внешнее соединение, записи, которые были отброшены из vTable2, добавляются в VTable 3, например, если вышеуказанный запрос был:
    выберите  u . * От  пользователей  у  левого  присоединиться к  группам  г  на  г . Userid  =  u . Идентификатор пользователя где  u . LastName  =  'Smith' и  u . FirstName  =  'Джон'
    все пользователи, которые не принадлежали ни к одной группе, будут добавлены обратно в Vtable3
  5. оценивается предложение WHERE, в этом случае в vTable4 будет добавлена ​​только информация о группе для пользователя John Smith.
  6. оценивается GROUP BY; если бы вышеуказанный запрос был:
    выберите  g . GroupName ,  подсчитайте ( g . * )  Как  NumberOfMembers от  пользователей  u  внутренних  групп присоединения  g на g . Userid = u . Группа идентификаторов пользователей по GroupName       
    vTable5 будет состоять из элементов, возвращенных из vTable4, упорядоченных группировкой, в данном случае GroupName
  7. предложение HAVING оценивается для групп, для которых предложение HAVING истинно, и вставляется в vTable6. Например:
    выберите  g . GroupName ,  подсчитайте ( g . * )  Как  NumberOfMembers от  пользователей  u  внутренних  групп присоединения  g на g . Userid = u . Группа идентификаторов пользователей по GroupName, имеющая count ( g . * ) > 5          
  8. список SELECT оценивается и возвращается как Vtable 7
  9. условие DISTINCT оценивается; повторяющиеся строки удаляются и возвращаются как Vtable 8
  10. условие ORDER BY оценивается, упорядочивая строки и возвращая VCursor9. Это курсор, а не таблица, потому что ANSI определяет курсор как упорядоченный набор строк (не реляционный).

Поддержка оконных функций поставщиками СУБД [ править ]

Реализация оконных функций у производителей реляционных баз данных и механизмов SQL сильно различается. Большинство баз данных поддерживают хотя бы некоторые разновидности оконных функций. Однако при более внимательном рассмотрении становится ясно, что большинство поставщиков реализуют только подмножество стандарта. В качестве примера возьмем мощное предложение RANGE. Только Oracle, DB2, Spark / Hive и Google Big Query полностью реализуют эту функцию. Совсем недавно производители добавили к стандарту новые расширения, например функции агрегирования массивов. Они особенно полезны в контексте выполнения SQL в распределенной файловой системе (Hadoop, Spark, Google BigQuery), где у нас более слабые гарантии совместного размещения данных, чем в распределенной реляционной базе данных (MPP). Вместо того, чтобы равномерно распределять данные по всем узлам, Механизмы SQL, выполняющие запросы к распределенной файловой системе, могут обеспечить гарантии совместного размещения данных за счет вложенности данных и, таким образом, избежания потенциально дорогостоящих объединений, включающих тяжелое перемешивание по сети. Определяемые пользователем агрегатные функции, которые можно использовать в оконных функциях, - еще одна чрезвычайно мощная функция.

Генерация данных в T-SQL [ править ]

Метод генерации данных на основе объединения всех

выбрать  1  a ,  1  b  объединить  все выбрать  1 ,  2  объединить  все выбрать  1 ,  3  объединить  все выбрать  2 ,  1  объединить  все выбрать  5 ,  1

SQL Server 2008 поддерживает «конструктор строк», указанный в стандарте SQL3 («SQL: 1999»).

выберите  * из  ( значения  ( 1 ,  1 ),  ( 1 ,  2 ),  ( 1 ,  3 ),  ( 2 ,  1 ),  ( 5 ,  1 ))  как  x ( a ,  b )

Ссылки [ править ]

  1. ^ Microsoft. «Соглашения о синтаксисе Transact-SQL» .
  2. ^ MySQL. «Синтаксис SQL SELECT» .
  3. ^ Пропуск предложения FROM не является стандартным, но разрешен большинством основных СУБД.
  4. ^ «Справочник по Transact-SQL». Справочник по языку SQL Server . Электронная документация по SQL Server 2005. Microsoft. 2007-09-15 . Проверено 17 июня 2007 .
  5. ^ SAS 9.4 Руководство пользователя процедуры SQL . Институт САС. 2013. с. 248. ISBN 9781612905686. Проверено 21 октября 2015 . Хотя аргумент UNIQUE идентичен аргументу DISTINCT, он не является стандартом ANSI.
  6. Леон, Алексис ; Леон, Мэтьюз (1999). «Устранение дубликатов - ВЫБРАТЬ с помощью DISTINCT». SQL: полный справочник . Нью-Дели: Tata McGraw-Hill Education (опубликовано в 2008 г.). п. 143. ISBN. 9780074637081. Проверено 21 октября 2015 . [...] ключевое слово DISTINCT [...] удаляет дубликаты из набора результатов.
  7. ^ Документация по PostgreSQL 9.1.24 - Глава 3. Расширенные функции
  8. ^ Программное обеспечение OpenLink. «9.19.10. Опция TOP SELECT» . docs.openlinksw.com . Проверено 1 октября 2019 года .
  9. ^ Ing. Оскар Бонилья, MBA
  10. ^ Внутри Microsoft SQL Server 2005: запросы T-SQL Ицик Бен-Ган, Любор Коллар и Деян Сарка

Источники [ править ]

  • Горизонтальное и вертикальное разбиение, электронная документация по Microsoft SQL Server 2000.

Внешние ссылки [ править ]

  • Оконные таблицы и оконные функции в SQL , Стефан Деслох
  • Синтаксис Oracle SELECT
  • Синтаксис Firebird SELECT
  • Синтаксис MySQL SELECT
  • Синтаксис PostgreSQL SELECT
  • Синтаксис SQLite SELECT