Разное

Exists sql описание: SQL. 12. EXISTS. [SQL.RU]

Содержание

EXISTS (Transact-SQL) — SQL Server



  • Чтение занимает 4 мин

В этой статье

Применимо к:Applies to: SQL ServerSQL Server (все поддерживаемые версии) SQL ServerSQL Server (all supported versions) База данных SQL AzureAzure SQL DatabaseБаза данных SQL AzureAzure SQL Database Управляемый экземпляр SQL AzureAzure SQL Managed InstanceУправляемый экземпляр SQL AzureAzure SQL Managed Instance Azure Synapse AnalyticsAzure Synapse AnalyticsAzure Synapse AnalyticsAzure Synapse Analytics Параллельное хранилище данныхParallel Data WarehouseПараллельное хранилище данныхParallel Data WarehouseПрименимо к:Applies to: SQL ServerSQL Server (все поддерживаемые версии) SQL ServerSQL Server (all supported versions) База данных SQL AzureAzure SQL DatabaseБаза данных SQL AzureAzure SQL Database Управляемый экземпляр SQL AzureAzure SQL Managed InstanceУправляемый экземпляр SQL AzureAzure SQL Managed Instance Azure Synapse AnalyticsAzure Synapse AnalyticsAzure Synapse AnalyticsAzure Synapse Analytics Параллельное хранилище данныхParallel Data WarehouseПараллельное хранилище данныхParallel Data Warehouse

Указывает вложенный запрос для проверки существования строк. Specifies a subquery to test for the existence of rows.

Синтаксические обозначения в Transact-SQLTransact-SQL Syntax Conventions

СинтаксисSyntax

EXISTS ( subquery )  

АргументыArguments

subquerysubquery
Ограниченная инструкция SELECT.Is a restricted SELECT statement. Ключевое слово INTO не допускается.The INTO keyword is not allowed. Дополнительные сведения о вложенных запросах см. в разделе SELECT (Transact-SQL).For more information, see the information about subqueries in SELECT (Transact-SQL).

Типы результатаResult Types

BooleanBoolean

Результирующие значенияResult Values

Возвращает значение TRUE, если вложенный запрос содержит хотя бы одну строку.Returns TRUE if a subquery contains any rows.

ПримерыExamples

A.A. Использование значения NULL во вложенном запросе для возвращения результирующего набораUsing NULL in a subquery to still return a result set

В следующем примере возвращается результирующий набор со значением NULL, указанным во вложенном запросе, и устанавливается значение TRUE с помощью ключевого слова EXISTS. The following example returns a result set with NULL specified in the subquery and still evaluates to TRUE by using EXISTS.

-- Uses AdventureWorks  
  
SELECT DepartmentID, Name   
FROM HumanResources.Department   
WHERE EXISTS (SELECT NULL)  
ORDER BY Name ASC ;  

Б.B. Сравнение запросов с помощью ключевых слов EXISTS и INComparing queries by using EXISTS and IN

В следующем примере сравниваются два семантически эквивалентных запроса.The following example compares two queries that are semantically equivalent. В первом запросе используется ключевое слово EXISTS, а во втором — ключевое слово IN.The first query uses EXISTS and the second query uses IN.

-- Uses AdventureWorks  
  
SELECT a.FirstName, a.LastName  
FROM Person.Person AS a  
WHERE EXISTS  
(SELECT *   
    FROM HumanResources.Employee AS b  
    WHERE a.BusinessEntityID = b.BusinessEntityID  
    AND a. LastName = 'Johnson') ;  
GO  

В следующем запросе используется ключевое слово IN.The following query uses IN.

-- Uses AdventureWorks  
  
SELECT a.FirstName, a.LastName  
FROM Person.Person AS a  
WHERE a.LastName IN  
(SELECT a.LastName  
    FROM HumanResources.Employee AS b  
    WHERE a.BusinessEntityID = b.BusinessEntityID  
    AND a.LastName = 'Johnson') ;  
GO  

Здесь приведен результирующий набор для каждого запроса.Here is the result set for either query.

FirstName                                          LastName
-------------------------------------------------- ----------
Barry                                              Johnson
David                                              Johnson
Willis                                             Johnson
 
(3 row(s) affected)

В.C. Сравнение запросов с помощью ключевых слов EXISTS и = ANYComparing queries by using EXISTS and = ANY

В следующем примере показаны два запроса для поиска магазинов, названия которых совпадают с названием поставщика. The following example shows two queries to find stores whose name is the same name as a vendor. В первом запросе используется ключевое слово EXISTS, а во втором — ключевое слово =``ANY.The first query uses EXISTS and the second uses =``ANY.

-- Uses AdventureWorks  
  
SELECT DISTINCT s.Name  
FROM Sales.Store AS s   
WHERE EXISTS  
(SELECT *  
    FROM Purchasing.Vendor AS v  
    WHERE s.Name = v.Name) ;  
GO  

В следующем запросе используется ключевое слово = ANY.The following query uses = ANY.

-- Uses AdventureWorks  
  
SELECT DISTINCT s.Name  
FROM Sales.Store AS s   
WHERE s.Name = ANY  
(SELECT v.Name  
    FROM Purchasing.Vendor AS v ) ;  
GO  

Г.D. Сравнение запросов с помощью ключевых слов EXISTS и INComparing queries by using EXISTS and IN

В следующем примере показаны запросы для поиска сотрудников подразделений, имена которых начинаются на P. The following example shows queries to find employees of departments that start with P.

-- Uses AdventureWorks  
  
SELECT p.FirstName, p.LastName, e.JobTitle  
FROM Person.Person AS p   
JOIN HumanResources.Employee AS e  
   ON e.BusinessEntityID = p.BusinessEntityID   
WHERE EXISTS  
(SELECT *  
    FROM HumanResources.Department AS d  
    JOIN HumanResources.EmployeeDepartmentHistory AS edh  
       ON d.DepartmentID = edh.DepartmentID  
    WHERE e.BusinessEntityID = edh.BusinessEntityID  
    AND d.Name LIKE 'P%') ;  
GO  

В следующем запросе используется ключевое слово IN.The following query uses IN.

-- Uses AdventureWorks  
  
SELECT p.FirstName, p.LastName, e.JobTitle  
FROM Person.Person AS p JOIN HumanResources.Employee AS e  
   ON e.BusinessEntityID = p.BusinessEntityID   
JOIN HumanResources.EmployeeDepartmentHistory AS edh  
   ON e.BusinessEntityID = edh.BusinessEntityID   
WHERE edh.DepartmentID IN  
(SELECT DepartmentID  
   FROM HumanResources. Department  
   WHERE Name LIKE 'P%') ;  
GO  

Д.E. Использование ключевого слова NOT EXISTSUsing NOT EXISTS

Работа ключевого слова NOT EXISTS противоположна работе ключевого слова EXISTS.NOT EXISTS works the opposite of EXISTS. Предложение WHERE в ключевом слове NOT EXISTS удовлетворяется, если вложенный запрос не возвратил никаких строк.The WHERE clause in NOT EXISTS is satisfied if no rows are returned by the subquery. В следующем примере выполняется поиск сотрудников, не входящих в состав подразделений, имена которых начинаются на P.The following example finds employees who are not in departments which have names that start with P.

SELECT p.FirstName, p.LastName, e.JobTitle  
FROM Person.Person AS p   
JOIN HumanResources.Employee AS e  
   ON e.BusinessEntityID = p.BusinessEntityID   
WHERE NOT EXISTS  
(SELECT *  
   FROM HumanResources.Department AS d  
   JOIN HumanResources.EmployeeDepartmentHistory AS edh  
      ON d. DepartmentID = edh.DepartmentID  
   WHERE e.BusinessEntityID = edh.BusinessEntityID  
   AND d.Name LIKE 'P%')  
ORDER BY LastName, FirstName  
GO  

Результирующий набор:Here is the result set.

FirstName                      LastName                       Title
------------------------------ ------------------------------ ------------
Syed                           Abbas                          Pacific Sales Manager
Hazem                          Abolrous                       Quality Assurance Manager
Humberto                       Acevedo                        Application Specialist
Pilar                          Ackerman                       Shipping & Receiving Superviso
François                       Ajenstat                       Database Administrator
Amy                            Alberts                        European Sales Manager
Sean                           Alexander                      Quality Assurance Technician
Pamela                         Ansman-Wolfe                   Sales Representative
Zainal                         Arifin                         Document Control Manager
David                          Barber                         Assistant to CFO
Paula                          Barreto de Mattos              Human Resources Manager
Shai                           Bassli                         Facilities Manager
Wanida                         Benshoof                       Marketing Assistant
Karen                          Berg                           Application Specialist
Karen                          Berge                          Document Control Assistant
Andreas                        Berglund                       Quality Assurance Technician
Matthias                       Berndt                         Shipping & Receiving Clerk
Jo                             Berry                          Janitor
Jimmy                          Bischoff                       Stocker
Michael                        Blythe                         Sales Representative
David                          Bradley                        Marketing Manager
Kevin                          Brown                          Marketing Assistant
David                          Campbell                       Sales Representative
Jason                          Carlson                        Information Services Manager
Fernando                       Caro                           Sales Representative
Sean                           Chai                           Document Control Assistant
Sootha                         Charncherngkha                 Quality Assurance Technician
Hao                            Chen                           HR Administrative Assistant
Kevin                          Chrisulis                      Network Administrator
Pat                            Coleman                        Janitor
Stephanie                      Conroy                         Network Manager
Debra                          Core                           Application Specialist
Ovidiu                         Crãcium                        Sr.  Tool Designer
Grant                          Culbertson                     HR Administrative Assistant
Mary                           Dempsey                        Marketing Assistant
Thierry                        D'Hers                         Tool Designer
Terri                          Duffy                          VP Engineering
Susan                          Eaton                          Stocker
Terry                          Eminhizer                      Marketing Specialist
Gail                           Erickson                       Design Engineer
Janice                         Galvin                         Tool Designer
Mary                           Gibson                         Marketing Specialist
Jossef                         Goldberg                       Design Engineer
Sariya                         Harnpadoungsataya              Marketing Specialist
Mark                           Harrington                     Quality Assurance Technician
Magnus                         Hedlund                        Facilities Assistant
Shu                            Ito                            Sales Representative
Stephen                        Jiang                          North American Sales Manager
Willis                         Johnson                        Recruiter
Brannon                        Jones                          Finance Manager
Tengiz                         Kharatishvili                  Control Specialist
Christian                      Kleinerman                     Maintenance Supervisor
Vamsi                          Kuppa                          Shipping & Receiving Clerk
David                          Liu                            Accounts Manager
Vidur                          Luthra                         Recruiter
Stuart                         Macrae                         Janitor
Diane                          Margheim                       Research & Development Enginee
Mindy                          Martin                         Benefits Specialist
Gigi                           Matthew                        Research & Development Enginee
Tete                           Mensa-Annan                    Sales Representative
Ramesh                         Meyyappan                      Application Specialist
Dylan                          Miller                         Research & Development Manager
Linda                          Mitchell                       Sales Representative
Barbara                        Moreland                       Accountant
Laura                          Norman                         Chief Financial Officer
Chris                          Norred                         Control Specialist
Jae                            Pak                            Sales Representative
Wanda                          Parks                          Janitor
Deborah                        Poe                            Accounts Receivable Specialist
Kim                            Ralls                          Stocker
Tsvi                           Reiter                         Sales Representative
Sharon                         Salavaria                      Design Engineer
Ken                            Sanchez                        Chief Executive Officer
José                           Saraiva                        Sales Representative
Mike                           Seamans                        Accountant
Ashvini                        Sharma                         Network Administrator
Janet                          Sheperdigian                   Accounts Payable Specialist
Candy                          Spoon                          Accounts Receivable Specialist
Michael                        Sullivan                       Sr.  Design Engineer
Dragan                         Tomic                          Accounts Payable Specialist
Lynn                           Tsoflias                       Sales Representative
Rachel                         Valdez                         Sales Representative
Garrett                        Vargar                         Sales Representative
Ranjit                         Varkey Chudukatil              Sales Representative
Bryan                          Walton                         Accounts Receivable Specialist
Jian Shuo                      Wang                           Engineering Manager
Brian                          Welcker                        VP Sales
Jill                           Williams                       Marketing Specialist
Dan                            Wilson                         Database Administrator
John                           Wood                           Marketing Specialist
Peng                           Wu                             Quality Assurance Supervisor
 
(91 row(s) affected)

Примеры: Azure Synapse AnalyticsAzure Synapse Analytics и Параллельное хранилище данныхParallel Data WarehouseExamples: Azure Synapse AnalyticsAzure Synapse Analytics and Параллельное хранилище данныхParallel Data Warehouse

Е.

F. Использование ключевого слова EXISTSUsing EXISTS

В следующем примере определяется, могут ли строки в таблице ProspectiveBuyer соответствовать строкам в таблице DimCustomer.The following example identifies whether any rows in the ProspectiveBuyer table could be matches to rows in the DimCustomer table. Запрос будет возвращать строки, только при совпадении значений LastName и BirthDate в двух таблицах.The query will return rows only when both the LastName and BirthDate values in the two tables match.

-- Uses AdventureWorks  
  
SELECT a.LastName, a.BirthDate  
FROM DimCustomer AS a  
WHERE EXISTS  
(SELECT *   
    FROM dbo.ProspectiveBuyer AS b  
    WHERE (a.LastName = b.LastName) AND (a.BirthDate = b.BirthDate)) ;  

Ж.G. Использование ключевого слова NOT EXISTSUsing NOT EXISTS

Работа ключевого слова NOT EXISTS противоположна работе ключевого слова EXISTS. NOT EXISTS works as the opposite as EXISTS. Предложение WHERE в ключевом слове NOT EXISTS удовлетворяется, если вложенный запрос не возвратил никаких строк.The WHERE clause in NOT EXISTS is satisfied if no rows are returned by the subquery. В следующем примере показан поиск всех строк в таблице DimCustomer, где LastName и BirthDate не соответствуют записям в таблице ProspectiveBuyers.The following example finds rows in the DimCustomer table where the LastName and BirthDate do not match any entries in the ProspectiveBuyers table.

-- Uses AdventureWorks  
  
SELECT a.LastName, a.BirthDate  
FROM DimCustomer AS a  
WHERE NOT EXISTS  
(SELECT *   
    FROM dbo.ProspectiveBuyer AS b  
    WHERE (a.LastName = b.LastName) AND (a.BirthDate = b.BirthDate)) ;  

См. также:See Also

Выражения (Transact-SQL) Expressions (Transact-SQL)
Встроенные функции (Transact-SQL) Built-in Functions (Transact-SQL)
WHERE (Transact-SQL)WHERE (Transact-SQL)



CREATE DATABASE — MariaDB Knowledge Base

Синтаксис

CREATE [OR REPLACE] {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
    [create_specification] . ..

create_specification:
    [DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] COLLATE [=] collation_name

Описание

CREATE DATABASE создает базу данных с заданым именем. Для того чтобы использовать данное выражение, Вам необходимо обладать соответствующими привилегиями (En). CREATE SCHEMA — это синоним выражения CREATE DATABASE. Если использовано выражение IF NOT EXISTS, то в ситуации, когда база данных уже существует, пользователю будет выдано предупреждение, а не сообщение об ошибке.

OR REPLACE
MariaDB starting with 10.1.3

Выражение OR REPLACE было добавлено в MariaDB в версии 10.1.3.

Если необязательное выражение OR REPLACE используется, то оно действует как сокращение для:

DROP DATABASE IF EXISTS db_name;
CREATE DATABASE db_name ...;
IF NOT EXISTS

При использовании выражения IF NOT EXISTS MariaDB вернет предупреждение, а не сообщение об ошибке в том случае, если база с указанным именем уже существует.

Примеры

CREATE DATABASE db1;
Query OK, 1 row affected (0.18 sec)

CREATE DATABASE db1;
ERROR 1007 (HY000): Can't create database 'db1'; database exists

CREATE DATABASE IF NOT EXISTS db1;
Query OK, 1 row affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+----------------------------------------------+
| Level | Code | Message                                      |
+-------+------+----------------------------------------------+
| Note  | 1007 | Can't create database 'db1'; database exists |
+-------+------+----------------------------------------------+

Настройка кодировки и правил сортировки (En). Подробнее смотри на странице «Настройка кодировки и правил сортировки» (En).

CREATE DATABASE czech_slovak_names 
  CHARACTER SET = 'keybcs2'
  COLLATE = 'keybcs2_bin';

Смотри также

Справочник SQL для выражений запросов, применяемых в ArcGIS—ArcGIS Pro

This topic describes the elements of common selection queries in ArcGIS. Выражения запросов в ArcGIS используют SQL.

Внимание:

Синтаксис SQL не работает при вычислении полей с помощью окна Калькулятора поля .

Часто используемые запросы: поиск строк

Строковые значения в выражениях всегда заключаются в одинарные кавычки, например:

STATE_NAME = 'California'

Строки в выражениях чувствительны к регистру, кроме случаев работы в базах геоданных в Microsoft SQL Server. Чтобы выполнять не чувствительный к регистру поиск в других источниках данных, можно использовать функцию SQL для преобразования всех значений в один регистр. Для источников данных на основе файлов, таких как файловые базы геоданных или шейп-файлы, для задания регистра выборки можно использовать функции UPPER или LOWER. Например, при помощи следующего выражения выбирается штат, имя которого написано как ‘Rhode Island’ или ‘RHODE ISLAND’:

UPPER(STATE_NAME) = 'RHODE ISLAND'

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

NAME = 'Alfie''s Trough'

При помощи оператора LIKE (вместо оператора = ) строится поиск частей строк. Например, данное выражение выбирает Mississippi и Missouri среди названий штатов США:

STATE_NAME LIKE 'Miss%'

Символ процента (%) означает, что на этом месте может быть что угодно – один символ или сотня, или ни одного. Если вы хотите использовать групповой символ, обозначающий один любой символ, используйте символ подчёркивания (_). Следующий пример показывает выражение для выбора имен Catherine Smith и Katherine Smith:

OWNER_NAME LIKE '_atherine Smith'

Можно также использовать операторы больше (>), меньше (<), больше или равно (>=), меньше или равно (<=), не равно (<>) и BETWEEN, чтобы выбирать строковые значения на основании их сортировки. Например, этот запрос выбирает все города в покрытии, названия которых начинаются с букв от М до Z:

CITY_NAME >= 'M'

Строковые функции могут использоваться для форматирования строк. Например функция LEFT возвращает определенное количество символов начиная с левого края строки. Данный запрос возвращает все штаты, начинающиеся на букву A:

LEFT(STATE_NAME,1) = 'A'

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

Часто используемые выражения: поиск значений NULL

Вы можете использовать ключевое слово NULL, чтобы отбирать объекты и записи, содержащие пустые поля. Перед ключевым словом NULL всегда стоит IS или IS NOT. Например, чтобы найти города, для которых не была введена численность населения по данным переписи 1996 года, можно использовать следующее выражение:

POPULATION IS NULL

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

POPULATION96 IS NOT NULL

Часто используемые выражения: поиск чисел

Точка (.) всегда используется в качестве десятичного разделителя, независимо от региональных настроек. В выражениях в качестве разделителя десятичных знаков нельзя использовать запятую.

Вы можете запрашивать цифровые значения, используя операторы равно (=), не равно (<>), больше (>), меньше (<), больше или равно (>=) и меньше или равно (<=), а также BETWEEN (между), например:

POPULATION >= 5000

Числовые функции можно использовать для форматирования чисел. Например функция ROUND округляет до заданного количества десятичных знаков данные в файловой базе геоданных:

ROUND(SQKM,0) = 500

Список поддерживаемых числовых функций см. в документации по СУБД.

Даты и время

Общие правила и часто используемые выражения

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

Поиск полей с датой требует внимания к синтаксису, необходимому для источника данных. Если вы создаете запрос в Конструкторе запросов в режиме Условие, правильный синтаксис будет сгенерирован автоматически. Ниже приведен пример запроса, который возвращает все записи после 1 января 2011, включительно, из файловой базы геоданных:

INCIDENT_DATE >= date '2011-01-01 00:00:00'

Даты хранятся в исходной базе данных относительно 30 декабря 1899 года, 00:00:00. Это действительно для всех источников данных, перечисленных здесь.

Цель этого подраздела – помочь вам в построении запросов по датам, но не по значениям времени. Когда со значением даты хранится не нулевое значение (например January 12, 1999, 04:00:00), то запрос по дате не возвратит данную запись, поскольку если вы задаете в запросе только дату для поля в формате дата – время, недостающие поля времени заполняются нулями, и выбраны будут только записи, время которых соответствует 12:00:00 полуночи.

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

  • Строка, отображаемая в SQL-запросе, может иметь только небольшое сходство со значением, показанным в таблице, особенно когда в нее входит время. Например время, введенное как 00:00:15, отображается в атрибутивной таблице как 12:00:15 AM с региональными настройками США, а сопоставимый синтаксис запроса Datefield = ‘1899-12-30 00:00:15’.
  • Атрибутивная таблица не имеет сведений об исходных данных, пока вы не сохраните изменения. Она сначала попытается отформатировать значения в соответствии с ее собственным форматом, затем, после сохранения изменений, она попытается подогнать получившиеся результаты в соответствии с базой данных. По этой причине, вы можете вводить время в шейп-файл, но обнаружите, что оно удаляется при сохранении ваших изменений. Поле будет содержать значение ‘1899-12-30’, которое будет отображаться как 12:00:00 AM или эквивалентно, в зависимости от ваших региональных настроек.

Синтаксис даты-времени для многопользовательских баз геоданных

Oracle
Datefield = date 'yyyy-mm-dd'

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

Альтернативный формат при запросах к датам в Oracle следующий:

Datefield = TO_DATE('yyyy-mm-dd hh:mm:ss','YYYY-MM-DD Hh34:MI:SS')

Второй параметр ‘YYYY-MM-DD Hh34:MI:SS’ описывает используемый при запросах формат. Актуальный запрос выглядит так:

Datefield = TO_DATE('2003-01-08 14:35:00','YYYY-MM-DD Hh34:MI:SS')

Вы можете использовать более короткую версию:

TO_DATE('2003-11-18','YYYY-MM-DD')

И снова записи, где время не равно нулю, не будут возвращены.

SQL Server
Datefield = 'yyyy-mm-dd hh:mm:ss'

Часть запроса hh:mm:ss может быть опущена, когда в записях не установлено время.

Ниже приведен альтернативный формат:

Datefield = 'mm/dd/yyyy'
IBM Db2
Datefield = TO_DATE('yyyy-mm-dd hh:mm:ss','YYYY-MM-DD Hh34:MI:SS')

Часть запроса hh:mm:ss не может быть опущена, даже если время равно 00:00:00.

PostgreSQL
Datefield = TIMESTAMP 'YYYY-MM-DD Hh34:MI:SS'
Datefield = TIMESTAMP 'YYYY-MM-DD'

Вы должны указать полностью временную метку при использовании запросов типа «равно», в или не будет возвращено никаких записей. Вы можете успешно делать запросы со следующими выражениями, если запрашиваемая таблица содержит записи дат с точными временными метками (2007-05-29 00:00:00 или 2007-05-29 12:14:25):

select * from table where date = '2007-05-29 00:00:00';

или

select * from table where date = '2007-05-29 12:14:25';

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

select * from table where date < '2007-05-29';
select * from table where date < '2007-05-29 12:14:25';
Файловые базы геоданных, шейп-файлы, покрытия и прочие файловые источники данных
Datefield = date 'yyyy-mm-dd'

Файловые базы геоданных поддерживают использование времени в поле даты, поэтому его можно добавить в выражение:

Datefield = date 'yyyy-mm-dd hh:mm:ss'

Шейп-файлы и покрытия не поддерживают использование времени в поле даты.

SQL, используемый в файловой базе геоданных, базируется на стандарте SQL-92.

Известные ограничения

Построение запросов к датам, находящимся в левой части (первой таблице) соединения, работает только для файловых источников данных, таких как файловые базы геоданных, шейп-файлы и таблицы DBF. Но возможен обходной путь при работе с другими, не файловыми, источниками, такими как многопользовательские данные, как описано ниже.

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

FC1. date = date #01/12/2001#
FC1.date = date '01/12/2001'

Чтобы запрос был выполнен успешно, можно создать вот такой запрос:

FC1.date = date '01/12/2001' and Table1.OBJECTID > 0

Так как запрос включает поля из обеих таблиц, будет использована ограниченная версия SQL. В этом выражении Table1.OBJECTID всегда > 0 для записей, которые сопоставлены в процессе создания соединения, поэтому это выражение всегда верно для всех строк, содержащих сопоставления соединения.

Чтобы быть уверенным, что каждая запись с FC1.date = date ’01/12/2001′ выбрана, используйте следующий запрос:

FC1.date = date '01/12/2001' and (Table1.OBJECTID IS NOT NULL OR Table1.OBJECTID IS NULL)

Такой запрос будет выбирать все записи с FC1.date = date ’01/12/2001′, независимо от того, есть ли сопоставление при соединении для каждой отдельной записи.

Комбинированные выражения

Составные запросы могут комбинироваться путем соединения выражений операторами AND (И) и OR (ИЛИ). Вот пример запроса для выборки всех домов с общей площадью более 1500 квадратных футов и гаражом более чем на три машины:

AREA > 1500 AND GARAGE > 3

Когда вы используете оператор OR (ИЛИ), по крайней мере одно из двух разделенных оператором выражений, должно быть верно для выбираемой записи, например:

RAINFALL < 20 OR SLOPE > 35

Используйте оператор NOT (НЕ) в начале выражения, чтобы найти объекты или записи, не соответствующие условию выражения, например:

NOT STATE_NAME = 'Colorado'

Оператор NOT можно комбинировать с AND и OR. Вот пример запроса, который выбирает все штаты Новой Англии за исключением штата Maine:

SUB_REGION = 'New England' AND NOT STATE_NAME = 'Maine'

Вычисления

Вычисления можно включить в запросы с помощью математических операторов +, –, * и /. Можно использовать вычисление между полем и числом, например:

AREA >= PERIMETER * 100

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

POP1990 / AREA <= 25

Приоритет выражения в скобках

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

HOUSEHOLDS > MALES * (POP90_SQMI + AREA)

Вы можете добавить скобки в режиме Редактирование SQL вручную, или использовать команды Группировать и Разгруппировать в режиме Условие, чтобы добавить или удалить их.

Подзапросы

Подзапрос – это запрос, вложенный в другой запрос и поддерживаемый только в базах геоданных. Подзапросы могут использоваться в SQL-выражении для применения предикативных или агрегирующих функций, или для сравнения данных со значениями, хранящимися в другой таблице и т.п. Это может быть сделано с помощью ключевых слов IN или ANY. Например этот запрос выбирает только те страны, которых нет в таблице indep_countries:

COUNTRY_NAME NOT IN (SELECT COUNTRY_NAME FROM indep_countries)

Покрытия, шейп-файлы и прочие файловые источники данных, не относящиеся к базам геоданных, не поддерживают подзапросы. Подзапросы, выполняемые на версионных многопользовательских классах объектов и таблицах, не возвращают объекты, которые хранятся в дельта-таблицах. Файловые базы геоданных имеют ограниченную поддержку подзапросов, описанных в данном разделе, в то время, как многопользовательские базы геоданных поддерживают их полностью. Информацию обо всех возможностях подзапросов к многопользовательским базам геоданных смотрите в документации по своей СУБД.

Этот запрос возвращает объекты, где GDP2006 больше, чем GDP2005 любых объектов, содержащихся в countries (странах):

GDP2006 > (SELECT MAX(GDP2005) FROM countries)

Поддержка подзапросов в файловых базах геоданных ограничена следующим:

Операторы

Ниже приведен полный список операторов, поддерживаемых файловыми базами геоданных, шейп-файлами, покрытиями и прочими файловыми источниками данных. Они также поддерживаются в многопользовательских базах геоданных, хотя для этих источников данных может требоваться иной синтаксис. Кроме нижеперечисленных операторов, многопользовательские базы геоданных поддерживают дополнительные возможности. Более подробную информацию см. в документации по своей СУБД.

Арифметические операторы

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

ОператорОписание

*

Арифметический оператор умножения

/

Арифметический оператор деления

+

Арифметический оператор сложения

Арифметический оператор вычитания

Арифметические операторы

Операторы сравнения

Операторы сравнения используются для сравнения одного выражения с другим.

ОператорОписание

<

Меньше . Может использоваться со строками (сравнение основывается на алфавитном порядке) и для числовых вычислений, а также дат.

<=

Меньше или равно. Может использоваться со строками (сравнение основывается на алфавитном порядке) и для числовых вычислений, а также дат.

<>

Не равно . Может использоваться со строками (сравнение основывается на алфавитном порядке) и для числовых вычислений, а также дат.

>

Больше . Может использоваться со строками (сравнение основывается на алфавитном порядке) и для числовых вычислений, а также дат.

>=

Больше или равно. Может использоваться со строками (сравнение основывается на алфавитном порядке) и для числовых вычислений, а также дат.

[NOT] BETWEEN x AND y

Выбирает запись, если она имеет значение, которое больше или равно x и меньше или равно y. Если перед ней стоит значение NOT, она выбирает запись, если та имеет значение вне указанного диапазона. Например это выражение выбирает все записи со значениями, которые больше или равны 1 и меньше или равны 10:

OBJECTID BETWEEN 1 AND 10

Вот эквивалент этого выражения:

OBJECTID >= 1 AND OBJECTID <= 10

Однако, выражение с оператором BETWEEN обрабатывается быстрее, если у вас поле проиндексировано.

[NOT] EXISTS

Возвращает TRUE (истинно), если подзапрос возвращает хотя бы одну запись; в противном случае возвращает FALSE (ложно). Например, данное выражение вернет TRUE, если поле OJBECTID содержит значение 50:

EXISTS (SELECT * FROM parcels WHERE OBJECTID = 50)

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

[NOT] IN

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

STATE_NAME IN ('Alabama', 'Alaska', 'California', 'Florida')

IS [NOT] NULL

Выбирает запись, если там в определенном поле есть нулевое значение. Если перед NULL стоит NOT, выбирает запись, где в определенном поле есть какое-то значение.

x [NOT] LIKE y [ESCAPE ‘escape-character’]

Используйте оператор LIKE (вместо оператора = ) с групповыми символами, если хотите построить запрос по части строки. Символ процента (%) означает, что на этом месте может быть что угодно – один символ или сотня, или ни одного. Если вы хотите использовать групповой символ, обозначающий один любой символ, используйте символ подчёркивания (_). Если вам нужен доступ к несимвольным данным, используйте функцию CAST. Например, этот запрос возвращает числа, начинающиеся на 8, из целочисленного поля SCORE_INT:

CAST (SCORE_INT AS VARCHAR(10)) LIKE '8%'

Для включения символа (%) или (_) в вашу строку поиска, используйте ключевое слово ESCAPE для указания другого символа вместо escape, который в свою очередь обозначает настоящий знак процента или подчёркивания. Например данное выражение возвращает все строки, содержащие 10%, такие как 10% DISCOUNT или A10%:

AMOUNT LIKE '%10$%%' ESCAPE '$'
Операторы сравнения

Логические операторы

ОператорОписание

AND

Соединяет два условия и выбирает запись, в которой оба условия являются истинными. Например, выполнение следующего запроса выберет все дома с площадью более 1 500 квадратных футов и гаражом на две и более машины:

AREA > 1500 AND GARAGE > 2

OR

Соединяет два условия и выбирает запись, где истинно хотя бы одно условие. Например выполнение следующего запроса выберет все дома с площадью более 1,500 квадратных футов или гаражом на две и более машины:

AREA > 1500 OR GARAGE > 2

NOT

Выбирает записи, не соответствующие указанному выражению. Например это выражение выберет все штаты, кроме Калифорнии (California):

NOT STATE_NAME = 'California'
Логические операторы

Операторы строковой операции

Оператор Описание
||

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

FIRST_NAME || MIDDLE_NAME || LAST_NAME

Функции

Ниже приведен полный список функций, поддерживаемых файловыми базами геоданных, шейп-файлами, покрытиями и прочими файловыми источниками данных. Функции также поддерживаются в многопользовательских базах геоданных, хотя в этих источниках данных может использоваться иной синтаксис или имена функций. Кроме нижеперечисленных функций, многопользовательские базы геоданных поддерживают дополнительные возможности. Более подробную информацию см. в документации по своей СУБД.

Функции дат

ФункцияОписание

CURRENT_DATE

Возвращает текущую дату.

EXTRACT(extract_field FROM extract_source)

Возвращает фрагмент extract_field из extract_source. Аргумент extract_source является выражением даты–времени. Аргументом extract_field может быть одно из следующих ключевых слов: YEAR, MONTH, DAY, HOUR, MINUTE или SECOND.

CURRENT TIME

Возвращает текущую дату.

Функции дат

Строковые функции

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

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

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

Строковые функции, перечисленные здесь, базируются на 1; то есть, первым символом в строке является символ 1.

ФункцияОписание

CHAR_LENGTH(string_exp)

Возвращает длину строкового выражения в символах.

LOWER(string_exp)

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

POSITION(character_exp IN character_exp)

Возвращает место первого символьного выражения во втором символьном выражении. Результат – число с точностью, определяемой реализацией и коэффициентом кратности 0.

SUBSTRING(string_exp FROM start FOR length)

Возвращает символьную строку, извлекаемую из string_exp, начинающуюся с символа, положение которого определяется символами start и length .

TRIM(BOTH | LEADING | TRAILING trim_character FROM string_exp)

Возвращает string_exp, укороченную на количество символов, указанное в аргументе trim_character, с начала, с конца или с обоих концов строки.

UPPER(string_exp)

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

Строковые функции

Числовые функции

Все числовые функции возвращают числовые значения.

Аргументы, обозначенные numeric_exp, float_exp или integer_exp могут быть именем столбца, результатом другой скалярной функции или числовой константой, где исходные данные могут быть представлены числовым типом.

ФункцияОписание

ABS(numeric_exp)

Возвращает абсолютное значение numeric_exp.

ACOS(float_exp)

Возвращает угол в радианах, равный арккосинусу float_exp.

ASIN(float_exp)

Возвращает угол в радианах, равный арксинусу float_exp.

ATAN(float_exp)

Возвращает угол в радианах, равный арктангенсу float_exp.

CEILING(numeric_exp)

Возвращает наименьшее целочисленное значение, большее или равное numeric_exp.

COS(float_exp)

Возвращает косинус float_exp, где float_exp — угол, выраженный в радианах.

FLOOR(numeric_exp)

Возвращает наибольшее целое значение, меньшее или равное numeric_exp.

LOG(float_exp)

Возвращает натуральный логарифм float_exp.

LOG10(float_exp)

Возвращает логарифм по основанию 10 float_exp.

MOD(integer_exp1, integer_exp2)

Возвращает результат деления integer_exp1 на integer_exp2.

POWER(numeric_exp, integer_exp)

Возвращает значение numeric_exp в степени integer_exp.

ROUND(numeric_exp, integer_exp)

Возвращает numeric_exp, округленное до integer_exp знаков справа от десятичной точки. Если integer_exp отрицательное, numeric_exp округляется до |integer_exp| знаков слева от десятичной запятой.

SIGN(numeric_exp)

Возвращает указатель знака numeric_exp. Если numeric_exp меньше нуля, возвращается -1. Если numeric_exp равно нулю, возвращается 0. Если numeric_exp больше нуля, возвращается 1.

SIN(float_exp)

Возвращает синус float_exp, где float_exp — угол, выраженный в радианах.

TAN(float_exp)

Возвращает тангенс float_exp, где float_exp — угол, выраженный в радианах.

TRUNCATE(numeric_exp, integer_exp)

Возвращает numeric_exp, округленное до integer_exp знаков справа от десятичной точки. Если integer_exp отрицательное, numeric_exp округляется до |integer_exp| знаков слева от десятичной запятой.

Числовые функции

Функция CAST

Функция CAST конвертирует значение в определенный тип данных. Синтаксис выглядит так:

CAST(exp AS data_type [(length)])

Пример:

CAST (SCORE_INT AS VARCHAR(10))

Аргумент exp может быть названием столбца, результатом другой скалярной функции или буквенным. Data_type может быть любым из следующих ключевых слов, и задается строчными или заглавными буквами: CHAR, VARCHAR, INTEGER, SMALLINT, REAL, DOUBLE, DATE, TIME, DATETIME, NUMERIC или DECIMAL.

Более подробно о функции CAST см. CAST and CONVERT.

Связанные разделы

Отзыв по этому разделу?

Техническая документация — Техническая документация — Помощь

Настройка БД MSSQL для хранения сессий

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

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\aspnet_regsql.exe

Проблема заключается в том, что мастер не показывает ошибки, если они возникают при его выполнении. Утилита aspnet_regsql.exe позволяет сделать экспорт скрипта, который выполняется на сервере MSSQL. Это делается следующей командой:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\aspnet_regsql.exe -S uXXXXX.mssql.masterhost.ru -U uXXXXX_user -P PASSWORD -d uXXXXX_name -ssadd -sstype c -sqlexportonly C:\ssdb.sql

uXXXXX.mssql.masterhost.ru — адрес сервера MSSQL
uXXXXX_user — нужный MSSQL-логин
uXXXXX_db — имя нужной базы данных MSSQL
PASSWORD — соответствующий пароль доступа к базе данных

После выполнения команды создастся файл C:\ssdb.sql с кодом скрипта для настройки базы. Откроем этот файл в любом текстовом редакторе. База данных уже создана, поэтому из кода убираем следующую часть:

/* Create and populate the session state database */

IF DB_ID(N'uXXXXX') IS NULL BEGIN
    DECLARE @cmd nvarchar(500)
    SET @cmd = N'CREATE DATABASE [uXXXXX]'
    EXEC(@cmd)
END
GO

На хостинговом MSSQL-сервере отключен SQL Agent, поэтому невозможно создание заданий. Убираем части кода, касаемые создания заданий:

Убираем часть 1:

/* Drop the DeleteExpiredSessions_Job */

DECLARE @jobname nvarchar(200)
SET @jobname = N' uXXXXX' + '_Job_DeleteExpiredSessions'

-- Delete the [local] job
-- We expected to get an error if the job doesn't exist.
PRINT 'If the job does not exist, an error from msdb.dbo.sp_delete_job is
expected.'

EXECUTE msdb.dbo.sp_delete_job @job_name = @jobname
GO

Убираем часть 2:

/* Create the job to delete expired sessions */

-- Add job category
-- We expect an error if the category already exists.
PRINT 'If the category already exists, an error from msdb.dbo.sp_add_category is expected.'
EXECUTE msdb.dbo.sp_add_category @name = N'[Uncategorized (Local)]'
GO

BEGIN TRANSACTION
    DECLARE @JobID BINARY(16)
    DECLARE @ReturnCode int
    DECLARE @nameT nchar(200)
    SELECT @ReturnCode = 0

    -- Add the job
    SET @nameT = N'uXXXXX' + '_Job_DeleteExpiredSessions'
    EXECUTE @ReturnCode = msdb. dbo.sp_add_job
            @job_id = @JobID OUTPUT,
            @job_name = @nameT,
            @owner_login_name = NULL,
            @description = N'Deletes expired sessions from the session state database.',
            @category_name = N'[Uncategorized (Local)]',
            @enabled = 1,
            @notify_level_email = 0,
            @notify_level_page = 0,
            @notify_level_netsend = 0,
            @notify_level_eventlog = 0,
            @delete_level= 0

    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

    -- Add the job steps
    SET @nameT = N'uXXXXX' + '_JobStep_DeleteExpiredSessions'
    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep
            @job_id = @JobID,
            @step_id = 1,
            @step_name = @nameT,
            @command = N'EXECUTE DeleteExpiredSessions',
            @database_name = N'uXXXXX',
            @server = N'',
            @subsystem = N'TSQL',
            @cmdexec_success_code = 0,
            @flags = 0,
            @retry_attempts = 0,
            @retry_interval = 1,
            @output_file_name = N'',
            @on_success_step_id = 0,
            @on_success_action = 1,
            @on_fail_step_id = 0,
            @on_fail_action = 2

    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

    EXECUTE @ReturnCode = msdb. dbo.sp_update_job @job_id = @JobID, @start_step_id = 1
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

    -- Add the job schedules
    SET @nameT = N'uXXXXX' + '_JobSchedule_DeleteExpiredSessions'
    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule
            @job_id = @JobID,
            @name = @nameT,
            @enabled = 1,
            @freq_type = 4,
            @active_start_date = 20001016,
            @active_start_time = 0,
            @freq_interval = 1,
            @freq_subday_type = 4,
            @freq_subday_interval = 1,
            @freq_relative_interval = 0,
            @freq_recurrence_factor = 0,
            @active_end_date = 99991231,
            @active_end_time = 235959

    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

    -- Add the Target Servers
    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)'
    IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

    COMMIT TRANSACTION
    GOTO   EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
GO
/*************************************************************/

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

Exec [dbo].[DeleteExpiredSessions]

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

Настройка сайта для работы с БД MSSQL для хранения сессий

Для настройки сайта достаточно внести в файл конфигурации web.config в раздел <system.web> следующие строки:

<sessionState mode="SQLServer"
   allowCustomSqlDatabase="true"
   sqlConnectionString="Data Source=uXXXXX.mssql.masterhost.ru;
   Initial Catalog=uXXXXX_db;uid=uXXXXX_user;pwd=PASSWORD;"
   cookieless="false"
   timeout="20"
/>

uXXXXX.mssql.masterhost.ru — адрес сервера MSSQL
uXXXXX_user — нужный MSSQL-логин
uXXXXX_db — имя нужной базы данных MSSQL
PASSWORD — соответствующий пароль доступа к базе данных

Скачать пример готового web. config

Пример кода для проверки хранения сессий в БД MSSQL

Для проверки корректности хранения сессий в базе данных MSSQL можно использовать такой код:

<%@ Page Language="VB" %>
<Script runat=server>
  Sub Session_Add(sender As Object, e As EventArgs)
        Session("MySession") = text1.Value
        span1.InnerHtml = "Session data updated! <P> Your session contains: <font color=red>" + Session("MySession").ToString() + "</font>"
  End Sub

  Sub CheckSession(sender As Object, e As EventArgs)
        If Session("MySession") Is DBNull.Value Then
            span1.InnerHtml = "NOTHING, SESSION DATA LOST!"
        Else
            span1.InnerHtml = "Your session contains: <font color=red>" + Session("MySession").ToString() + "</font>"
        End If
  End Sub
</Script>

<form id="Form1" runat=server>
  <input id=text1 type=text runat=server>
  <input id="Submit1" type=submit runat=server
              OnServerClick="Session_Add" Value="Add to Session State">
  <input id="Submit2" type=submit runat=server
              OnServerClick="CheckSession" Value="View Session State">
</form>
<hr size=1>
<font size=6><span id=span1 runat=server/></font>

Код нужно сохранить в файле с расширением . aspx и загрузить файл на площадку в директорию сайта

НОУ ИНТУИТ | Лекция | Формирование запросов средствами языка SQL

Аннотация: В лекции обсуждаются вопросы применения оператора SELECT для построения сложных запросов.

Формирование запросов средствами языка SQL

Оператор SELECT

Оператор SELECT позволяет формировать запрос к базе данных. В результате выполнения этого оператора СУБД формирует результирующий набор (иногда также называемый набором данных). Если этот оператор был введен в интерактивном режиме взаимодействия с базой данных, то результат отображается в виде таблицы в текущем диалоговом окне. На рис. 3.1 приведен пример выполнения оператора SELECT , извлекающего данные всех столбцов из таблицы dept.

Рис.
3.1.
выполнение оператора SELECT

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

Оператор SELECT имеет в стандарте SQL92 следующее формальное описание:

SELECT [DISTINCT]
     { {function_agregate | expr [AS new_field_name] } .,:
     | specification.*
     | *
     [INTO list_variable]
     FROM {{ имя_таблицы [AS] [table_alias] [(field .,:)]} 
               | {subquery [AS] subquery_alas [(field .,:)]} 
               | union_table 
               | constructor_of_table_value 
               | {TABLE имя_таблицы [AS] alias [(field .,:)]} 
          } .,:
     [WHERE condition]
     [GROUP BY {{ имя_таблицы | alias }.field} .,: {COLLATE name}] 
      [HAVING condition]
     [{ UNION | INTERSECT | EXCEPT } [ALL]
       [CORRESPONDING [BY (field.,:)]]
       SELECT_operator | {TABLE имя_таблицы} | constructor_of_table_value      
	   [ORDER BY] {{field_result [ASC|DESC]}.,:}
             |{{ integer [ASC|DESC]}.,:} ;

Листинг
3.1.
Формальное описание оператора SELECT

intuit.ru/2010/edi»>Для выполнения запроса требуется привилегия SELECT на все таблицы, участвующие в запросе.

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

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

SELECT tbl1.f1, tbl2.f1 FROM tbl1, tbl2;
  • Фраза FROM определяет одну или несколько таблиц или подзапросов, используемых для извлечения данных.
  • Фраза INTO используется только во встроенном SQL, указывая переменные, в которые записывается результат запроса. При этом формируемый результирующий набор может содержать только одну строку.
  • Фраза WHERE определяет условие, которому должны удовлетворять все строки, используемые для формирования результирующего набора.

Во всех операциях сравнения языка SQL применяется трехзначная логика ( 3VL ). Предикат, указываемый фразой WHERE, может принимать одно из следующих значений: TRUE, FALSE или UNKNOWN. Значение UNKNOWN получается при сравнении значения NULL с любым другим значением, включая значение NULL.

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

Кроме стандартных операторов сравнения, таких как =, <>, >, <, >=, <= могут быть использованы следующие операторы:

Вариант сравненияПредикат
SOMEANYAll
Результат сравнения конструктора значений строки с каждой строкой из набора строк, полученных как подзапрос, равен TRUETRUETRUETRUE
Результат выполнения подзапроса не содержит строк для сравненияFALSEFALSETRUE
Результат сравнения конструктора значений строки с каждой строкой из набора строк, полученных как подзапрос, равен FALSEFALSEFALSEFALSE
Хотя бы один из результатов сравнения конструктора значений строки со строкой из набора строк, полученных как подзапрос, равен TRUETRUETRUEUNKNOWN

intuit.ru/2010/edi»>Для примера обозначим строку запроса заключенной в скобки, а строки подзапроса — разделенными пробелом. Так, следующий предикат вернет значение TRUE:

(10, 1)> ANY (12, 2 0, NULL 5, 20),

так как первая строка из подзапроса удовлетворяет условию. А предикат

(NULL, NULL) = ANY (12, 2 NULL, NULL 5, 20)

вернет значение UNKNOWN, так как сравнение NULL c NULL в результате дает UNKNOWN. Предикат

(10, 1)> ALL (12, 0 0, NULL 5, 20)

вернет значение FALSE, так как сравнение строки (10,1) с каждой строкой подзапроса возвращает значение FALSE.

ТОП 30 статей для изучения языка T-SQL – Уровень «Начинающий»

Приветствую Вас на сайте Info-Comp.ru! В этом материале я представляю Вам 30 лучших своих статей, посвященных языку T-SQL, которые отлично подойдут начинающим программистам для изучения языка T-SQL.

Данную подборку статей я назвал – Уровень «Начинающий», ведь все представленные здесь статьи не требуют особой подготовки и знаний языка T-SQL и Microsoft SQL Server.

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

Таким образом, данный материал можно было бы смело назвать «Курс по изучения языка T-SQL для начинающих», так как последовательно читая все представленные здесь статьи Вы будете изучать язык T-SQL примерно так же, как на специализированных курсах по T-SQL.

Однако за счет того, что здесь отсутствует какая-либо методика обучения, направленная на комплексное изучение языка T-SQL, а представлена всего лишь подборка подходящих статьей, при этом даже такое количество статей не охватывает тот объем информации, который требуется начинающим, данный материал я назвал именно так, т. е. – «ТОП 30 статей для изучения языка T-SQL – Уровень «Начинающий».

Почему Уровень «Начинающий»? Потому что это — первый материал из цикла статей на данную тему, будут еще подборки: Уровень «Продвинутый» и Уровень «Эксперт». Поэтому следите за выходом новых статей в наших группах в социальных сетях: ВКонтакте, Facebook, Одноклассники, Twitter и Tumblr.

Все статьи написаны лично мной (некоторые уже достаточно давно, поэтому не судите строго) и расположены они на этом же сайте в открытом доступе, поэтому Вам не придётся посещать какие-то сторонние ресурсы для того, чтобы прочитать их.

Итак, давайте приступать.

Что такое SQL

Статья – Что такое SQL. Назначение и основа

Из данного материала Вы узнаете, что такое SQL вообще, для чего нужен и используется данный язык, я расскажу про диалекты языка SQL, а также про базы данных и системы управления базами данных. Здесь представлена основа, база, с которой необходимо начать свое знакомство с языком T-SQL (Что такое T-SQL?).

Как создать и выполнить SQL запрос

Статья – Как создать и выполнить SQL запрос к базе данных. Обзор основных инструментов

Из этой статьи Вы узнаете, какими инструментами создавать и выполнять SQL запросы к базе данных, будут рассмотрены инструменты не только для Microsoft SQL Server, но и для других популярных СУБД. Таким образом, в материале представлены основные инструменты, с которыми Вам придётся работать при разработке инструкций на языке SQL.

Создание базы данных

Статья – Создание базы данных в Microsoft SQL Server – инструкция для новичков

В этом материале представлена подробная инструкция для новичков по созданию базы данных в Microsoft SQL Server. Здесь рассмотрены основные этапы создания базы данных, а также два способа создания БД. Без знаний, представленных в этой статье, создать базу не получится.

Создание таблиц

Статья Создание таблиц в Microsoft SQL Server (CREATE TABLE) – подробная инструкция

В этой статье рассмотрен процесс создания таблиц в Microsoft SQL Server, Вы узнаете, как это делается в графическом интерфейсе, а также как создавать таблицы на языке T-SQL. Здесь, как и во всех других материалах, представлены практические примеры со скриншотами и пояснениями.

Изменение таблиц

Статья Изменение таблиц в Microsoft SQL Server или как добавить, удалить, изменить столбец в таблице?

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

Переименование столбцов

Статья Как переименовать столбец таблицы в Microsoft SQL Server на T-SQL?

Из данного материала Вы узнаете, как переименовать столбец таблицы в Microsoft SQL Server на языке T-SQL уже после создания этой таблицы. В некоторых случаях это бывает очень полезно, так как Вам не нужно пересоздавать всю таблицу целиком.

Добавление данных

Статья Инструкция INSERT INTO в Transact-SQL – несколько способов добавления данных в таблицу

В этой статье рассмотрено несколько способов добавления данных в базу Microsoft SQL Server. Иными словами, Вы узнаете, как добавляются новые строки в таблицы на языке T-SQL с использованием инструкции INSERT INTO.

Обновление данных

Статья Инструкция UPDATE в T-SQL — обновление данных в Microsoft SQL Server

В этом материале подробно рассмотрена инструкция UPDATE языка T-SQL, с помощью которой происходит обновление данных в таблицах Microsoft SQL Server. Таким образом, Вы узнаете, как изменять уже существующие данные в базе.

Вычисляемые столбцы

Статья Вычисляемые столбцы в Transact-SQL

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

Инструкция SELECT INTO

Статья Инструкция SELECT INTO в T-SQL или как создать таблицу на основе SQL запроса?

Из данного материала Вы узнаете, как создать таблицу на основе результата SQL запроса в Microsoft SQL Server с использованием инструкции SELECT INTO. Будет рассмотрено несколько примеров с подробным описанием.

Типы данных в T-SQL

Статья Типы данных в T-SQL (Microsoft SQL Server)

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

Оператор BETWEEN

Статья BETWEEN в T-SQL – примеры использования логического оператора

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

Оператор EXISTS

Статья Логический оператор EXISTS в T-SQL. Описание и примеры

Из данной статьи Вы узнаете, как работает логический оператор EXISTS в языке T-SQL, который принимает и обрабатывает вложенный SQL запрос (SELECT) с целью проверки существования строк. В качестве результата возвращает значения TRUE или FALSE. Здесь будет рассмотрено несколько примеров его использования в разных конструкциях.

Команда USE

Статья Как изменить контекст базы данных в Microsoft SQL Server? Команда USE

Из данного материала Вы узнаете, как можно сменить контекст базы данных в Microsoft SQL Server, будет рассмотрена команда USE, которая используется в T-SQL как раз для этого.

Составные операторы присваивания

Статья Составные операторы присваивания в Transact-SQL

Из данной статьи Вы узнаете, какие существуют составные операторы в языке Transact-SQL, которые используются для упрощения написания операций присваивания, и как их использовать.

Инструкция TRUNCATE TABLE

Статья Инструкция TRUNCATE TABLE в Transact-SQL

В этом материале рассмотрена инструкция TRUNCATE TABLE, которую можно использовать для удаления данных. Вы узнаете, чем отличается TRUNCATE TABLE от DELETE, и какие преимущества нам дает эта инструкция.

Группировка данных GROUP BY

Статья – Transact-SQL группировка данных GROUP BY

В данной статье рассмотрена конструкция GROUP BY языка T-SQL, которая используется для группировки данных. Данная конструкция очень полезна, и она используется достаточно часто для анализа различных данных.

Объединение JOIN

Статья Язык SQL – объединение JOIN

В этом материале рассмотрены основы объединения данных из разных таблиц, Вы узнаете, что такое INNER, LEFT, RIGHT и CROSS JOIN, и, конечно же, посмотрите на примеры использования этих конструкций.

Объединение UNION и UNION ALL

Статья Объединение UNION и UNION ALL в SQL – описание и примеры

В этой статье рассмотрено объединение UNION и UNION ALL, которое используется для объединения результирующего набора данных нескольких SQL запросов. Вы узнаете, для чего может потребоваться этот тип объединения, и посмотрите на примеры использования UNION и UNION ALL.

Хранимые процедуры

Статья Хранимые процедуры в T-SQL — создание, изменение, удаление

Из данной статьи Вы узнаете, что такое хранимые процедуры в языке T-SQL, научитесь создавать, изменять и удалять хранимые процедуры.

Ограничения

Статья Ограничения в Microsoft SQL Server — что это такое и как их создать?

Ограничения – это специальные объекты в Microsoft SQL Server, с помощью которых можно задать правила допустимости определенных значений в столбцах с целью обеспечения автоматической целостности базы данных.

В данной статье будут рассмотрены основы и примеры создания ограничений в Microsoft SQL Server, таких как: PRIMARY KEY, FOREIGN KEY, CHECK и других.

Основы индексов

Статья Основы индексов в Microsoft SQL Server

В этой статье рассмотрены основы индексов в Microsoft SQL Server, Вы узнаете, для чего нужны индексы, какие типы индексов бывают, а также как создаются, оптимизируются и удаляются индексы на языке T-SQL.

Вложенные запросы

Статья Вложенные запросы в T-SQL – описание и примеры

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

Выражение CASE

Статья Примеры использования выражения CASE в Transact-SQL

CASE – это инструкция, которая проверяет список условий и возвращает соответствующий результат. Если говорить в целом о программировании, то CASE – это что-то вроде многократного использования конструкции IF-ELSE, во многих языках есть похожая конструкция SWITCH.

В этом материале рассмотрено выражение CASE языка Transact-SQL: описание, синтаксис, а также примеры использования выражения CASE.

Как получить первые (или последние) строки запроса

Статья Как в SQL получить первые (или последние) строки запроса? TOP или OFFSET?

Из данного материала Вы узнаете два способа получения первых или последних строк SQL запроса, первый — с применением фильтра TOP, второй — используя конструкцию OFFSET-FETCH.

Операция MERGE

Статья Операция MERGE в языке Transact-SQL – описание и примеры

MERGE – операция в языке T-SQL, при которой происходит обновление, вставка или удаление данных в таблице на основе результатов соединения с данными другой таблицы или SQL запроса. Другими словами, с помощью MERGE можно осуществить слияние двух таблиц, т.е. синхронизировать их.

В этом материале будут рассмотрены основы и примеры использования операции MERGE.

Оператор DROP IF EXISTS

Статья Инструкция DROP IF EXISTS в языке T-SQL

У инструкции DROP, которая используется для удаления объектов базы данных, есть дополнительный параметр IF EXISTS, благодаря которому можно предварительно проверить существование объекта, перед его непосредственным удалением.

В этой статье рассмотрена инструкция DROP IF EXISTS и примеры ее использования.

Конструкция OFFSET-FETCH

Статья OFFSET-FETCH в T-SQL – описание и примеры использования

OFFSET-FETCH – это конструкция языка T-SQL, которая является частью ORDER BY, и позволяет применять фильтр к результирующему, уже отсортированному, набору данных.

В данном материале рассмотрена конструкция OFFSET-FETCH, а также приведены примеры использования этой конструкции.

Как вывести повторяющиеся значения в столбце

Статья Как вывести повторяющиеся значения в столбце на T-SQL? Microsoft SQL Server

Из данного материала Вы узнаете, как вывести повторяющиеся значения в столбце таблицы на языке T-SQL, будут рассмотрены конкретные примеры.

Основы программирования на T-SQL

Статья Основы программирования на T-SQL

В этом материале рассмотрены основы программирования на языке T-SQL, Вы узнаете, что такое пакеты, переменные, научитесь использовать условные конструкции, циклы, а также познакомитесь с командами GOTO, WAITFOR, RETURN и другими.

Виталий Трунин

Автор всех статей. Разработчик T-SQL

Задать вопрос

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

На сегодня это все, до новых встреч на сайте Info-Comp.ru!

добейтесь большего от SQL Server » Статьи о Microsoft Windows. Установка, администрирование, ускорение и оптимизация Microsoft Windows 7, Windows 8, Windows XP, и Windows 10

Я расскажу, как обращаться к данным, которые содержатся в XML-строках, передаваемых хранимым процедурам, и как выводить XML-данные. На рис. 1 показана высокоуровневая архитектура этих операций. Я познакомлю вас со следующими синтаксическими конструкциями T-SQL, связанными с XML:

— sp_xml_preparedocument;
— OPENXML;
— sp_xml_removedocument;
— FOR XML EXPLICIT.

Рис. 1. Применение на практике некоторых новшеств в синтаксисе T-SQL

Простой пример: пакетная проверка пользовательского ввода
В SQL Server 2000 нет встроенного типа для хранения XML-данных. Для хранения XML-строк в переменных или полях таблиц применяют тип (n)(var)char или (n)text. Почти во всех случаях, встречающихся при разработке, такие переменные оказываются входными параметрами хранимых процедур; поэтому так будет и в моем примере. (Следует заметить, что передача кода T-SQL между уровнями всегда рискованна с точки зрения безопасности и, как правило, оказывается не лучшим вариантом с точки зрения производительности; это достаточно веские причины, чтобы никогда так не поступать.)

Рассмотрим хранимую процедуру sptxValidateLookupData, разработанную моей группой несколько лет назад. Она предназначена для проверки на допустимость данных, вводимых пользователем в рабочий процесс определенной системы. Чтобы свести к минимуму количество обменов с базой данных, разработчики системы решили накапливать весь пользовательский ввод и передавать информацию, которую требуется проверять на допустимость, в базу данных в одном XML-документе. Хранимая процедура выполняет проверку на допустимость и возвращает вызывающему процессу результаты, также помещая их в один XML-документ. Процедура sptxValidateLookupData обслуживает несколько разных рабочих процессов, поэтому в одном и том же пакете могут запрашиваться проверки «существует» или «не существует» для любого значения (datum) или области (domain). В следующем фрагменте кода показаны типичные входные XML-данные этой хранимой процедуры:

<ValidateData>
<Validate Type=»Countries» Name=»CountryCode»
  Value=»JA» Test=»Not Exists»/>
<Validate Type=»Countries» Name=»CountryCode»
  Value=»BO1″ Test=»Exists»/>
<Validate Type=»Languages» Name=»LanguageCode»
  Value=»EN» Test=»Exists»/>
<Validate Type=»ContactPreferences»
  Name=»ContactPreferenceCode» Value=»EN»
  Test=»Exists»/></ValidateData>

В корневом узле содержатся подузлы , описывающие, какую проверку нужно выполнить. Type задает область, для которой выполняется проверка, Name — проверяемый атрибут, а Test — тип проверки (существует ли значение Value в поле, указанном атрибутом Name, в области Type). Заметьте: этот фрагмент XML-данных описывает четыре операции проверки на допустимость для трех областей, но версия хранимой процедуры, которая используется в настоящее время, поддерживает 17 областей и любое число проверок. Таким образом, у нас есть компонент проверки на допустимость, обеспечивающий многократное использование кода, отличную расширяемость и высокую производительность, удобный в сопровождении, а главное — простой до неприличия!

Результаты также возвращаются в XML-формате. Если все проверки для данного потока возвратили TRUE (т. е. если истинны утверждения, задаваемые в узлах Test), возвращается пустой тэг . Однако, если какие-либо проверки потерпели неудачу, возвращается список ошибок:

<Errors>
<Error ErrorMessage=»JA exists in Countries»
  FieldName=»CountryCode»/>
<Error ErrorMessage=»BO1 does not exist in Countries»
  FieldName=»CountryCode»/>
<Error ErrorMessage=»EN does not exist in ContactPreferences»
  FieldName=»ContactPreferenceCode»/>
</Errors>

Работа с XML-данными
В SQL Server 2000 XML-данные передаются процессу T-SQL как простые строки. Чтобы с ними можно было работать как с реляционными или иерархическими данными, необходимо дать SQL Server «понять», что это XML-данные, — «подготовить» их. Для этого вызывается системная хранимая процедура sp_xml_preparedocument. Давайте посмотрим начало хранимой процедуры sptxValidateLookupData (листинг 1). Системная хранимая процедура sp_xml_preparedocument считывает XML-текст, передаваемый как входной параметр (параметр @XMLString в вызове в листинге 1), затем передает текст анализатору MSXML и формирует проанализированный документ, готовый к обработке функцией OPENXML, возвращающей набор записей.

Этот документ является иерархическим представлением различных узлов XML-документа (элементов, атрибутов, текста, комментариев и т.д.). Оно хранится в кэше сервера, максимальный размер которого равен одной восьмой от общего объема памяти сервера. Поэтому необходимо аккуратно работать с этим внутренним представлением в интенсивно используемых системах или в средах с ограниченным объемом памяти.

Листинг 1. Хранимая процедура sptxValidateLookupData

create procedure sptxValidateLookupData
@XMLString ntext
as

set nocount on

declare @idoc int, @Name nvarchar(30), @Value nvarchar(300),
        @Test nvarchar(30), @Result int, @Type nvarchar(30),
        @TestResult int

—    Готовим входные XML-данные к выборке с помощью OPENXML
exec sp_xml_preparedocument @idoc OUTPUT, @XMLString

Процедура sp_xml_preparedocument возвращает описатель (значение @idoc в вызове в листинге 1), через который можно обращаться к созданному внутреннему представлению XML-документа. Это значение используется в качестве параметра функции OPENXML, возвращающей набор записей для оператора SELECT. OPENXML — «мост» к подготовленному XML-документу, и ее можно указывать в операторе SELECT аналогично таблице или представлению (листинг 2).

Я создал и заполнил табличную переменную, чтобы не выполнять многократные вызовы OPENXML, которые были бы менее эффективны, чем многократное обращение к табличной переменной. Лучше копировать содержимое XML-документов в табличные переменные, чтобы избавиться от многократного неэффективного доступа к XML-данным (хотя, если вы собираетесь обратиться к XML-данным только один раз, просто выполните запрос с OPENXML без предварительного создания табличной переменной). Второй оператор на рис. 3 копирует входные XML-данные в табличную переменную @tempValidateLookupData.

Листинг 2. Создание табличной переменной

—  Создаем табличную переменную для хранения
—  данных о проверках
declare @tempValidateLookupData table (
    [Type] nvarchar(30),
    [Name] nvarchar(30),
    [Value] nvarchar(300),
    [Test] nvarchar(30),
    [TestResult] int
)

—  Заполняем табличную переменную данными о проверках,
—  которые требуется выполнить
insert @tempValidateLookupData
select [Type], [Name], [Value], [Test], NULL
    from OPENXML (@idoc, ‘/ValidateData/Validate’)
    with ([Type] nvarchar(30), [Name] nvarchar(30),
        [Value] nvarchar(300), [Test] nvarchar(30))

Знакомимся с OPENXML
Теперь повнимательнее рассмотрим синтаксис OPENXML:

OPENXML(idoc int [in],rowpattern nvarchar[in],[flags byte[in]])
[WITH (SchemaDeclaration | TableName)]

Параметр idoc — описатель документа, созданный для внутреннего представления XML-документа. Другими словами, это значение, ранее возвращенное процедурой sp_xml_preparedocument. Заметьте: в одной хранимой процедуре можно манипулировать несколькими XML-строками. В таком случае необходимо вызвать sp_xml_preparedocument для каждой XML-строки и объявить по отдельной переменной для хранения каждого возвращенного описателя.

Параметр rowpattern идентифицирует узлы XML-документа, связанного с описателем idoc, которые должны обрабатываться как записи. Он указывает XML-анализатору, где в XML-документе находятся интересующие вас данные.

Параметр flags задает, какое сопоставление используется при запросе в первую очередь — ориентированное на атрибуты (attribute-centric) или на элементы (element-centric). Если этот параметр опущен, SQL Server 2000 по умолчанию применяет сопоставление, ориентированное на атрибуты, что вполне подходит для нашего случая. Подробнее об этом параметре см. описание функции OPENXML в SQL Server Books Online.

Раздел WITH функции OPENXML указывает SQL Server 2000, какие типы данных SQL сопоставляются содержимому XML-документа. Вы можете либо явно задать поля, либо сослаться на таблицу базы данных с подходящей структурой. Каждое поле XML-документа, используемое в операторе SELECT, должно присутствовать в разделе WITH (описываться явно или в таблице). В рассматриваемом примере:

—  Заполняем табличную переменную данными о проверках,
—  которые требуется выполнить
insert @tempValidateLookupData
select [Type], [Name], [Value], [Test], NULL
    from OPENXML (@idoc, ‘/ValidateData/Validate’)
    with ([Type] nvarchar(30), [Name] nvarchar(30),
    [Value] nvarchar(300), [Test] nvarchar(30))

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

Освобождение памяти
Внутреннее представление XML-документа остается в памяти, пока соединение процесса с сервером не будет закрыто или сброшено или пока память не освободят явно. Следует вызывать системную процедуру sp_xml_removedocument как можно раньше, поскольку лучше поскорее освободить эту память, чтобы на сервере было доступно больше ресурсов (для освобождения памяти требуется указать описатель):

—    Освобождаем память сервера, которая используется
—    образом входных XML-данных, созданным OPENXML
exec sp_xml_removedocument @idoc

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

После разбора XML-документа процедура sptxValidateLookupData выполняет большой оператор IF, чтобы выбрать требуемую проверку и занести в переменную @TestResult значение, соответствующее результатам проверки. Затем результаты проверки используются при обновлении табличной переменной (листинг 3).

Листинг 3. Выбор требуемой проверки

—  Заносим результаты проверок в табличную переменную,
—  перебирая записи, у которых поле TestResult содержит NULL
while exists (select TestResult from @tempValidateLookupData
    where TestResult is null) begin

—  Извлекаем данные из записи, проверяемой на допустимость
    Select top 1 @Type=[Type], @Name=[Name], @Value=Value,
        @Test=Test
        from @tempValidateLookupData
        where TestResult is null

—  И выполняем соответствующую проверку…

—  Проверка для области Countries (взята в качестве примера)
    if    @Type = ‘Countries’ begin
        if exists (select CountryCode from dbo. Country where
            CountryCode = convert(nvarchar(4), @Value))
            select    @TestResult =
            CASE    when @Test = ‘Exists’ then 1
                else 0
            end
        else
            select    @TestResult =
            CASE    when @Test = ‘Not Exists’ then 1
                else 0
            end
    end

—  (16 других проверок на допустимость опущены для краткости)

—  Обновляем соответствующую запись: заносим в нее результат
—  проверки
    update   @tempValidateLookupData
    set      TestResult = @TestResult
    where    Name = @Name
    and      Value = @Value
    and      Test = @Test
end

SQL-синтаксис для возврата XML-данных
Итак, проверки на допустимость выполнены, теперь нужно возвратить результаты вызывающему процессу. SQL Server 2000 поддерживает несколько механизмов вывода XML-данных с помощью директивы FOR XML оператора SELECT. Прежде чем продолжить рассказ о sptxValidateLookupData, я кратко рассмотрю еще кое-какие новшества в синтаксисе языка SQL.

В SQL Server 2000 три типа разделов FOR XML. FOR XML RAW и FOR XML AUTO позволяют сформировать простейший XML-вывод с минимумом усилий и соответственно с отсутствием контроля над форматом вывода. Большинство уважающих себя программистов для SQL Server 2000 используют FOR XML EXPLICIT. При применении режима EXPLICIT программист полностью контролирует вид XML-документа, возвращаемого запросом, и должен обеспечить синтаксическую корректность и допустимость XML-документа.

Как выглядит содержимое раздела EXPLICIT?
Существует ряд жестких синтаксических требований к формированию запросов, использующих режим EXPLICIT. Каждый запрос с режимом EXPLICIT должен содержать два поля метаданных. У первого поля, указываемого в операторе SELECT, должно быть имя Tag и тип int. Это номер тэга текущего элемента, т. е. фактически номер типа поддерева. У второго поля должно быть имя Parent и тоже тип int. Оно содержит номер тэга элемента, который является родителем текущего элемента. Эти поля описывают иерархию XML-дерева. Если поле Parent записи имеет значение 0 или NULL, его данные располагаются на вершине XML-иерархии. Кроме этого единственного исключения, все значения поля Parent должны соответствовать ранее объявленным значениям тэгов. Заметьте: набор результатов должен содержать ровно одну запись, у которой поле Parent содержит 0 или NULL, причем она должна быть первой в наборе результатов (если имеется более одной записи, у которой номер тэга родителя равен 0 или NULL, генерируется XML-фрагмент).

Имена остальных полей запроса должны соответствовать специальному формату, который определяет, как имена элементов связаны с номерами тэгов, и задает имена атрибутов для генерируемых XML-данных. Имя поля имеет формат:

[ElementName!TagNumber!AttributeName!Directive]

где ElementName — имя элемента (если в качестве ElementName указано «Countries», результатом будет ), а TagNumber — номер тэга элемента. TagNumber вместе с полями метаданных Tag и Parent описывает иерархию XML-дерева. Каждый TagNumber соответствует одному ElementName, а AttributeName является именем XML-атрибута (если оно задано).

Рассмотрение использования Directive и работы в нескольких ситуациях, в которых AttributeName может быть NULL, выходит за рамки данной статьи. Раздел «Using Explicit Mode» в SQL Server 2000 Books Online — превосходный источник дополнительной информации.

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

Вернемся к sptxValidateLookupData. Как вы помните, в описании процедуры говорилось о двух форматах возвращаемого набора результатов. Если все проверки данного пакета возвратили TRUE, я возвращаю пустой тэг . Но если какая-то проверка потерпела неудачу, я возвращаю XML-документ со списком ошибок.

В листинге 4 приведен код процедуры sptxValidateLookupData, который генерирует наборы результатов с помощью FOR XML EXPLICIT. Синтаксис режима EXPLICIT довольно многословен, поэтому рассмотрим его по частям. Первая ветвь оператора IF обрабатывает простую ситуацию, когда все мои проверки возвратили TRUE:

— Если все проверки на допустимость пройдены,
— возвращаем пустой набор XML-данных…
if not exists (select [TestResult] from
    @tempValidateLookupData where TestResult = 0)
    select 1 as TAG, 0 as parent,
    NULL as [Results!1!]
    for xml explicit

Листинг 4. Применение FOR XML EXPLICIT

— Если все проверки на допустимость пройдены,
— возвращаем пустой набор XML-данных…
if not exists (select [TestResult] from
    @tempValidateLookupData where TestResult = 0)
    select 1 as TAG, 0 as parent,
    NULL as [Results!1!]
    for xml explicit

— …иначе возвращаем XML-данные о проверках,
— потерпевших неудачу
else
    select 1 as TAG, 0 as parent,
    NULL as [Errors!1!],
    NULL as [Error!2!],
    NULL as [Error!2!ErrorMessage],
    NULL as [Error!2!FieldName]

    union all

    select 2 as TAG, 1 as parent,
    NULL,
    NULL,
    ltrim(rtrim(value)) + ‘ does not exist in ‘ + type,
    [name]

    from @tempValidateLookupData
    where [TestResult] = 0
    and test = ‘Exists’

    union all

    select 2 as TAG, 1 as parent,
    NULL,
    NULL,
    ltrim(rtrim(value)) + ‘ already exists in ‘ + type,
    [name]

    from @tempValidateLookupData
    where [TestResult] = 0
    and test = ‘Not Exists’

    for xml explicit

Поскольку AttributeName не задано, этот оператор создаст единственный XML-элемент Results без атрибутов и потомков:

Ветвь ELSE гораздо интереснее: в ней я формирую XML-данные о проверках, потерпевших неудачу, объединяя операторы SELECT с помощью UNION. Как показано в листинге 5, каждый запрос формирует узлы выходных XML-данных определенного типа (который описывается в комментариях после каждого запроса).

Листинг 5. Формирование узлов

— …иначе возвращаем XML-данные о проверках,
— потерпевших неудачу
else
    select 1 as TAG, 0 as parent,
    NULL as [Errors!1!],
    NULL as [Error!2!],
    NULL as [Error!2!ErrorMessage],
    NULL as [Error!2!FieldName]

—    (приведенный выше запрос формирует элемент <Errors>)

    union all

    select 2 as TAG, 1 as parent,
    NULL,
    NULL,
    ltrim(rtrim(value)) + ‘ does not exist in ‘ + type,
    [name]

    from @tempValidateLookupData
    where [TestResult] = 0
    and test = ‘Exists’

—    (приведенный выше запрос формирует узлы вида
—    <Error ErrorMessage=»BO1 does not exist in Countries»
—        FieldName=»CountryCode»/>)

    union all

    select 2 as TAG, 1 as parent,
    NULL,
    NULL,
    ltrim(rtrim(value)) + ‘ exists in ‘ + type,
    [name]

    from @tempValidateLookupData
    where [TestResult] = 0
    and test = ‘Not Exists’

—    (приведенный выше запрос формирует узлы вида
—    <Error ErrorMessage=»JA exists in Countries»
—        FieldName=»CountryCode»/>)

    for xml explicit

Заметьте: запросы, объединенные UNION, упорядочены так, чтобы каждый потомок шел сразу за своим родителем, хотя узлы могут быть потомками нескольких подзапросов (у запросов «exists» и «not exists» поля tag и parent имеют одинаковые значения). Когда запросы, объединенные с помощью UNION, обрабатываются в режиме FOR XML EXPLICIT, сериализатор FOR XML вычисляет имена полей

[ElementName!TagNumber!AttributeName!Directive]

и значения полей метаданных Tag и Parent, а затем выводит XML-иерархию, заданную программистом:

<Errors>
  <Error ErrorMessage=»JA exists in Countries»
    FieldName=»CountryCode»/>
  <Error ErrorMessage=»BO1 does not exist in Countries»
    FieldName=»CountryCode»/>
  <Error ErrorMessage=»EN does not exist in ContactPreferences»
    FieldName=»ContactPreferenceCode»/>
</Errors>

Миссия выполнена
Имея в распоряжении описанные выше средства, вы можете запрашивать и генерировать XML-данные в среде SQL Server 2000. Но какими бы мощными ни были эти средства, SQL Server 2005 предоставит еще больше программных функций всем специалистам, обрабатывающим XML-данные с помощью T-SQL, и позволит добиться еще большей производительности.

XML-программирование в SQL Server 2005
При разработке SQL Server 2005 Microsoft значительно усовершенствовала поддержку XML. Последние два года я создавал новую систему на основе внутренних версий этого продукта (рай для SQL-разработчика!) и рад сообщить, что программистов, использующих XML, ждет масса хороших новостей.

Весь синтаксис поддержки XML, введенный в SQL Server 2000, не изменился, но в SQL Server 2005 в него внесена уйма дополнений. Я рассмотрю некоторые из них и покажу, как изменится хранимая процедура sptxValidateLookupData, рассмотренная в статье. Я также расскажу о следующих новшествах SQL Server 2005: о типах данных XML, FOR XML PATH, TYPE, синтаксисе nodes().

Все методики работы с XML, применяемые в SQL Server 2000 (передача XML-строк хранимым процедурам в параметрах типа ntext, манипулирование ими с помощью sp_xml_preparedocument, sp_xml_removedocument, FOR XML EXPLICIT и OPENXML), доступны и в SQL Server 2005, но в новой версии появились средства, позволяющие использовать другие подходы. Как только вы поработаете с новым синтаксисом, вам уже не захочется возвращаться к старому.

В SQL Server 2005 внесены революционные изменения в сам механизм хранения данных, в частности введены три новых типа данных: nvarchar(max), varbinary(max) и xml. В T-SQL возникали сложности с обработкой значений типа ntext, поэтому, если вы собираетесь по-прежнему использовать те же конструкции работы с XML, что и в SQL Server 2000, имеет смысл отказаться от ntext и перейти на nvarchar(max) и varbinary(max). Однако наиболее интересен тип данных XML, также добавленный в ядро сервера. Он предоставляет программистам ряд совершенно новых возможностей.

Переработанный пример
Как вы помните, хранимая процедура sptxValidateLookupData, рассмотренная в статье, поддерживает единый процесс пакетной проверки пользовательского ввода в Web-страницы, позволяющий выполнить несколько разных проверок на допустимость для значений, получаемых из гетерогенных источников. Директивы, описывающие проверки, передаются хранимой процедуре в одном XML-документе. Хранимая процедура выполняет проверки и возвращает результаты вызывающему процессу, тоже в одном XML-документе.

Новая версия процедуры
Как и в процедуре для SQL Server 2000, я помещаю содержимое входного XML-документа в табличную переменную. Но я больше не вызываю sp_xml_preparedocument и не применяю OPENXML. Как показано в листинге 6, я изменил тип данных параметра на xml (с ntext) и воспользовался новым синтаксисом nodes().

Листинг 6. Использование типа данных XML

create procedure sptxValidateLookupData
@XMLString xml
as

set nocount on

declare @idoc int, @Name nvarchar(30), @Value nvarchar(300),
        @Test nvarchar(30), @Result int, @Type nvarchar(30),
        @TestResult int

—  Создаем табличную переменную для хранения
—  данных о проверках
declare @tempValidateLookupData table (
    [Type] nvarchar(30),
    [Name] nvarchar(30),
    [Value] nvarchar(300),
    [Test] nvarchar(30),
    [TestResult] int
)

—  Заполняем табличную переменную данными о проверках,
—  которые требуется выполнить
insert  @tempValidateLookupData
select  ref. value (‘@Type’, ‘[nvarchar](30)’),
        ref.value (‘@Name’, ‘[nvarchar](30)’),
        ref.value (‘@Value’, ‘[nvarchar](300)’),
        ref.value (‘@Test’, ‘[nvarchar](30)’),
        NULL
        from @XMLString.nodes(‘/ValidateData/Validate’)
        as node(ref)

Давайте повнимательнее рассмотрим метод nodes. Он позволяет получить ссылку для каждой записи, которая соответствует элементу Validate, находящемуся внутри элемента ValidateData переменной @XMLString. Эта переменная описывается инструкцией AS NODE(ref) как набор записей, представляющий узлы (node rowset). В каждом определении поля в операторе SELECT вызывается метод value, извлекающий значение заданного атрибута. Он выполняется для каждой записи, поэтому для каждого элемента Validate с параметрами проверки генерируется по одной записи.

В каждом вызове метода value указывается имя атрибута элемента, извлекаемого из XML-узла. Перед именем атрибута ставится символ @, и оно заключается в одинарные кавычки, затем (также в кавычках) указывается тип данных SQL, сопоставляемый атрибуту.

Логика выполнения проверок на допустимость в новой версии sptxValidateLookupData осталась прежней.

Возврат результатов
Как вы помните, в исходной спецификации процедуры описывались два формата возвращаемого набора записей. Если все проверки данного пакета возвратили TRUE, набор должен содержать пустой тэг . Однако, если какие-то проверки потерпели неудачу, нужно вернуть список XML-данных об ошибках.

В листинге 7 приведен новый код процедуры sptxValidateLookupData, генерирующий наборы результатов с помощью FOR XML PATH, TYPE. Обратите внимание, насколько этот синтаксис компактнее старого синтаксиса FOR XML EXPLICIT.

Листинг 7. Применение FOR XML PATH

— Если все проверки на допустимость пройдены,
— возвращаем пустой набор XML-данных…
if not exists (select [TestResult]
    from @tempValidateLookupData
    where TestResult = 0)
    select null
    for xml path (‘Results’), type

— …иначе возвращаем XML-данные о проверках,
— потерпевших неудачу
else
    select null,
    (
        select
        ltrim(rtrim(value)) + ‘ does not exist in ‘ +
        type AS ‘@ErrorMessage’,
        [name] AS ‘@FieldName’

        from @tempValidateLookupData
        where [TestResult] = 0
        and test = ‘Exists’

        for xml path (‘Error’), type
    ),
    (
        select
        ltrim(rtrim(value)) + ‘ already exists in ‘ +
        type AS ‘@ErrorMessage’,
        [name] AS ‘@FieldName’

        from @tempValidateLookupData
        where [TestResult] = 0
        and test = ‘Not Exists’

        for xml path (‘Error’), type
    )
    for xml path (‘Errors’), type

Как и прежде, первая ветвь оператора IF обрабатывает простой случай, когда все проверки возвратили TRUE:

— Если все проверки на допустимость пройдены,
— возвращаем пустой набор XML-данных. ..
if not exists (select [TestResult] from
  @tempValidateLookupData where TestResult = 0)
    select null
    for xml path (‘Results’), type

Ветвь ELSE, как и раньше, формирует XML-данные для проверок, потерпевших неудачу, но на сей раз с помощью нескольких вложенных операторов SELECT FOR XML PATH, TYPE. Явно заданные имена полей указывают SQL Server, что их нужно использовать в качестве имен XML-атрибутов (перед ними должен идти символ @, их надо заключить в одинарные кавычки). Директивы FOR XML PATH (‘Error’) указывают серверу, что требуется обернуть XML-данные, создаваемые внутренними операторами SELECT, элементом Error, а директива FOR XML PATH (‘Errors’) — что внешний SELECT формирует корневой элемент ‘Errors’. Таким образом, этот SQL-код генерирует тот же набор результатов, что и прежде, но с помощью гораздо более лаконичного запроса, чем запрос с FOR XML EXPLICIT.

Может, на первый взгляд это и не очевидно, но отказ от запросов SELECT, объединенных операторами UNION, выполняемых при использовании FOR XML EXPLICIT, делает код гетерогенных запросов гораздо компактнее и удобнее в сопровождении. Например, недавно моя группа переписала одну пользовательскую функцию SQL Server 2000 длиной в 5000 строк (большую их часть составлял 43-уровневый запрос с FOR XML EXPLICIT). Новый синтаксис позволил уложиться в 497 строк.

Если вы хотите по-прежнему придерживаться модели с UNION (что сомнительно), то можете написать второй запрос SELECT так, как показано в листинге 8. Этот подход не сработал бы, если бы ваши внутренние XML-узлы содержали разные количества атрибутов. Одно из основных преимуществ нового вложенного синтаксиса в том, что в отличие от операторов SELECT с UNION количество полей в подзапросах не обязательно должно быть одинаковым. Тем не менее, пример в листинге 8 демонстрирует еще одну новую конструкцию — FOR XML ROOT. Она позволяет объявить корневой элемент возвращаемых XML-данных, не создавая явный запрос SELECT. Дополнительные сведения по этому вопросу см. в статье «XML Options in Microsoft SQL Server 2005» (EN).

Листинг 8. Применение FOX XML ROOT

select
    ltrim(rtrim(value)) + ‘ does not exist in    ‘ +
    type AS ‘@ErrorMessage’,
    [name] AS ‘@FieldName’

    from @tempValidateLookupData
    where [TestResult] = 0
    and test = ‘Exists’

        union all

        select
        ltrim(rtrim(value)) + ‘ already exists in ‘ +
        type AS ‘@ErrorMessage’,
        [name] AS ‘@FieldName’

        from @tempValidateLookupData
        where [TestResult] = 0
        and test = ‘Not Exists’

        for xml path (‘Error’), root
            (‘Errors’), type

С помощью этих новых средств SQL Server 2005 вы можете запрашивать и генерировать XML-данные еще эффективнее, чем раньше. Я рассмотрел лишь небольшую часть возможностей нового синтаксиса. SQL Server 2005 позволяет делать с XML-данными почти все, что угодно. Если вас интересуют ресурсы с самой свежей информацией о SQL Server 2005, посетите сайт «Introducing SQL Server 2005» (EN).



Оцените статью: Голосов 1

SQL EXISTS, SQL Subquery EXISTS — с примерами

Что делает WHERE EXISTS?

WHERE EXISTS проверяет наличие каких-либо записей в подзапросе.
EXISTS возвращает истину, если подзапрос возвращает одну или несколько записей.
Условие EXISTS обычно используется с коррелированными подзапросами.

Синтаксис SQL EXISTS

Общий синтаксис:

ВЫБЕРИТЕ имена столбцов
  ОТ имя-таблицы
 ГДЕ СУЩЕСТВУЕТ
      (ВЫБЕРИТЕ имя-столбца
         ОТ имя-таблицы
        ГДЕ условие)
 

ПОСТАВЩИК
Идентификатор
Название компании
Контактное имя
Город
Страна
Телефон
Факс

Идентификатор продукта

ПРОДУКТ

ProductName
SupplierId
UnitPrice
Package
Is Снят с производства

SQL EXISTS

Пример

Задача: Найти поставщиков
с продуктами более 100 долларов.

ВЫБЕРИТЕ CompanyName
  ОТ поставщика
 ГДЕ СУЩЕСТВУЕТ
       (ВЫБЕРИТЕ ProductName
          ОТ продукта
         ГДЕ SupplierId = Supplier.Id
           И UnitPrice> 100)
 

Примечание. Это коррелированный подзапрос , поскольку подзапрос ссылается на включающий запрос (с Supplier.Id).

Результат: 2 записи

Название компании
Plutzer Lebensmittelgroßmärkte AG
Aux joyeux ecclésiastiques

СУЩЕСТВУЕТ (Transact-SQL) — SQL Server

  • 5 минут на чтение

В этой статье

Применимо к: SQL Server (все поддерживаемые версии) База данных SQL AzureAzure SQL Managed InstanceAzure Synapse Analytics Хранилище параллельных данных

Задает подзапрос для проверки существования строк.

Соглашения о синтаксисе Transact-SQL

Синтаксис

  СУЩЕСТВУЕТ (подзапрос)
  

Аргументы

подзапрос
Это ограниченный оператор SELECT. Ключевое слово INTO недопустимо. Для получения дополнительной информации см. Информацию о подзапросах в SELECT (Transact-SQL).

Типы результатов

логический

Значения результата

Возвращает TRUE, если подзапрос содержит какие-либо строки.

Примеры

А.Использование NULL в подзапросе для возврата набора результатов

В следующем примере возвращается набор результатов с NULL , указанным в подзапросе, и все еще оценивается как ИСТИНА с использованием EXISTS .

  - Использует AdventureWorks
  
ВЫБЕРИТЕ ИД отдела, имя
ОТ HumanResources. Отдел
ГДЕ СУЩЕСТВУЕТ (ВЫБРАТЬ NULL)
ЗАКАЗАТЬ Имя ASC;
  

B. Сравнение запросов с использованием EXISTS и IN

В следующем примере сравниваются два семантически эквивалентных запроса. Первый запрос использует EXISTS , а второй запрос использует IN .

  - Использует AdventureWorks
  
ВЫБЕРИТЕ a.FirstName, a.LastName
ОТ Person.Person КАК
ГДЕ СУЩЕСТВУЕТ
(ВЫБРАТЬ *
    ОТ HumanResources.Сотрудник AS b
    ГДЕ a.BusinessEntityID = b.BusinessEntityID
    И a.LastName = 'Johnson');
ИДТИ
  

В следующем запросе используется IN .

  - Использует AdventureWorks
  
ВЫБЕРИТЕ a.FirstName, a.LastName
ОТ человека.Человек КАК
ГДЕ a.LastName IN
(ВЫБЕРИТЕ a.LastName
    ОТ HumanResources.Сотрудник AS b
    ГДЕ a.BusinessEntityID = b.BusinessEntityID
    И a.LastName = 'Johnson');
ИДТИ
  

Вот набор результатов для любого запроса.

  Имя Фамилия
-------------------------------------------------- ----------
Барри Джонсон
Дэвид Джонсон
Уиллис Джонсон
 
(3 строки затронуты)
  

С.Сравнение запросов с использованием EXISTS и = ANY

В следующем примере показаны два запроса для поиска магазинов, название которых совпадает с названием продавца. Первый запрос использует EXISTS , а второй использует = `` ANY .

  - Использует AdventureWorks
  
ВЫБЕРИТЕ РАЗЛИЧНОЕ имя
ИЗ Sales.Store AS s
ГДЕ СУЩЕСТВУЕТ
(ВЫБРАТЬ *
    ОТ Purchasing.Vendor AS v
    ГДЕ s.Name = v.Name);
ИДТИ
  

В следующем запросе используется = ANY .

  - Использует AdventureWorks
  
ВЫБЕРИТЕ РАЗЛИЧНОЕ имя
ИЗ Sales.Store AS s
ГДЕ s.Name = ЛЮБОЙ
(ВЫБЕРИТЕ v.Name
    ОТ Purchasing.Vendor AS v);
ИДТИ
  

D. Сравнение запросов с использованием EXISTS и IN

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

  - Использует AdventureWorks
  
ВЫБЕРИТЕ p.FirstName, p.LastName, e.JobTitle
ОТ Person.Person AS p
ПРИСОЕДИНЯЙТЕСЬ к HumanResources.Сотрудник AS e
   НА e.BusinessEntityID = p.BusinessEntityID
ГДЕ СУЩЕСТВУЕТ
(ВЫБРАТЬ *
    ОТ HumanResources. Отдел AS d
    ПРИСОЕДИНЯЙТЕСЬ HumanResources. EmployeeDepartmentHistory AS edh
       ON d.DepartmentID = edh.DepartmentID
    ГДЕ e.BusinessEntityID = edh.BusinessEntityID
    AND d.Name КАК 'P%');
ИДТИ
  

В следующем запросе используется IN .

  - Использует AdventureWorks
  
ВЫБЕРИТЕ p.FirstName, p.LastName, e.JobTitle
ОТ Person.Person AS p ПРИСОЕДИНЯЙТЕСЬ к HumanResources.Сотрудник AS e
   НА e.BusinessEntityID = p.BusinessEntityID
ПРИСОЕДИНЯЙТЕСЬ HumanResources.EmployeeDepartmentHistory AS edh
   НА e.BusinessEntityID = edh.BusinessEntityID
ГДЕ edh.
(ВЫБЕРИТЕ ИД отдела
   ОТ HumanResources. Отдел
   ГДЕ Имя LIKE 'P%');
ИДТИ
  

E. Использование NOT EXISTS

NOT EXISTS работает противоположно EXISTS. Предложение WHERE в NOT EXISTS выполняется, если подзапрос не возвращает ни одной строки. В следующем примере выполняется поиск сотрудников, не работающих в отделах, имена которых начинаются с P .

  ВЫБРАТЬ p.FirstName, p.LastName, e. JobTitle
ОТ Person.Person AS p
ПРИСОЕДИНЯЙТЕСЬ к HumanResources.Employee AS e
   НА e.BusinessEntityID = p.BusinessEntityID
ГДЕ НЕ СУЩЕСТВУЕТ
(ВЫБРАТЬ *
   ОТ HumanResources. Отдел AS d
   ПРИСОЕДИНЯЙТЕСЬ HumanResources.EmployeeDepartmentHistory AS edh
      ON d.DepartmentID = edh.DepartmentID
   ГДЕ e.BusinessEntityID = edh.BusinessEntityID
   И d.Имя КАК 'P%')
ЗАКАЗАТЬ ПО Фамилии, Имени
ИДТИ
  

Вот результат.

  Имя Фамилия Заголовок
------------------------------ -------------------- ---------- ------------
Сайед Аббас, Тихоокеанский менеджер по продажам
Хазем Аболрус, менеджер по обеспечению качества
Умберто Асеведо, специалист по применению
Пилар Акерман Руководитель службы доставки и получения
Франсуа Аженстат Администратор базы данных
Эми Альбертс, менеджер по продажам в Европе
Шон Александр Техник по обеспечению качества
Памела Ансман-Вулф, торговый представитель
Зайнал Арифин Менеджер по контролю документов
Дэвид Барбер Помощник финансового директора
Паула Баррето де Маттос Менеджер по персоналу
Шай Бассли Менеджер по эксплуатации
Ванида Бенсхооф Ассистент по маркетингу
Карен Берг, специалист по применению
Карен Берге Помощник по контролю документов
Андреас Берглунд Специалист по обеспечению качества
Маттиас Берндт, ответственный за доставку и прием
Джо Берри Дворник
Джимми Бишофф Стокер
Майкл Блайт, торговый представитель
Дэвид Брэдли, менеджер по маркетингу
Кевин Браун Ассистент по маркетингу
Дэвид Кэмпбелл, торговый представитель
Джейсон Карлсон Менеджер информационных служб
Фернандо Каро, торговый представитель
Шон Чай Помощник по контролю документов
Sootha Charncherngkha Технический специалист по обеспечению качества
Хао Чен Помощник по кадровым вопросам
Кевин Крисулис Сетевой администратор
Пэт Коулман Дворник
Стефани Конрой Сетевой менеджер
Специалист по приложениям Debra Core
Ovidiu Crãcium Sr. Конструктор инструментов
Грант Калбертсон, помощник по управлению персоналом
Мэри Демпси Ассистент по маркетингу
Дизайнер инструментов Тьерри Д'Эрс
Терри Даффи, вице-президент по проектированию
Сьюзан Итон Стокер
Терри Эминхайзер Специалист по маркетингу
Гейл Эриксон, инженер-конструктор
Дженис Гэлвин Дизайнер инструментов
Мэри Гибсон, специалист по маркетингу
Йосеф Голдберг, инженер-конструктор
Сария Харнпадунгсатая Специалист по маркетингу
Марк Харрингтон, техник по обеспечению качества
Магнус Хедлунд Помощник по эксплуатации
Торговый представитель Шу Ито
Стивен Цзян, менеджер по продажам в Северной Америке
Уиллис Джонсон Рекрутер
Браннон Джонс Финансовый менеджер
Тенгиз Харатишвили Специалист по контролю
Кристиан Кляйнерман Начальник технического обслуживания
Вамси Куппа, ответственный за доставку и приемку
Дэвид Лю менеджер по работе с клиентами
Видур Лутра Рекрутер
Стюарт Макрэй Дворник
Дайан Маргхейм, инженер по исследованиям и разработкам
Минди Мартин, специалист по льготам
Джиджи Мэтью, инженер по исследованиям и разработкам
Торговый представитель Тете Менса-Аннан
Рамеш Мейяппан, специалист по применению
Дилан Миллер, менеджер по исследованиям и развитию
Линда Митчелл, торговый представитель
Барбара Морленд Бухгалтер
Лаура Норман Финансовый директор
Крис Норред Специалист по контролю
Торговый представитель Дже Пак
Ванда Паркс Дворник
Дебора По, специалист по дебиторской задолженности
Ким Раллс Стокер
Цви Рейтер Торговый представитель
Шэрон Салавария, инженер-конструктор
Кен Санчес Главный исполнительный директор
Хосе Сараива, торговый представитель
Майк Симанс Бухгалтер
Администратор сети Ашвини Шарма
Джанет Шепердигиан Специалист по счетам к оплате
Candy Spoon Специалист по дебиторской задолженности
Майкл Салливан-старшийИнженер-проектировщик
Драган Томич Специалист по кредиторской задолженности
Линн Цофлиас Торговый представитель
Рэйчел Вальдес, торговый представитель
Торговый представитель Гарретта Варгара
Ранджит Варки Чудукатил Торговый представитель
Брайан Уолтон, специалист по дебиторской задолженности
Цзянь Шо Ван Технический менеджер
Брайан Велкер, вице-президент по продажам
Джилл Уильямс, специалист по маркетингу
Дэн Уилсон, администратор базы данных
Специалист по маркетингу Джона Вуда
Пэн У Супервайзер по обеспечению качества
 
(91 строка (и) затронута)
  

Примеры: Azure Synapse Analytics и хранилище параллельных данных

Ф.

Использование EXISTS

В следующем примере определяется, могут ли какие-либо строки в таблице ProspectiveBuyer совпадать со строками в таблице DimCustomer . Запрос вернет строки только в том случае, если значения LastName и BirthDate в двух таблицах совпадают.

  - Использует AdventureWorks
  
ВЫБЕРИТЕ a.LastName, a.BirthDate
ОТ DimCustomer КАК
ГДЕ СУЩЕСТВУЕТ
(ВЫБРАТЬ *
    ОТ dbo.ProspectiveBuyer AS b
    ГДЕ (a.LastName = b.Фамилия) И (a.BirthDate = b.BirthDate));
  

G. Использование NOT EXISTS

NOT EXISTS работает как противоположность EXISTS. Предложение WHERE в NOT EXISTS выполняется, если подзапрос не возвращает ни одной строки. В следующем примере выполняется поиск строк в таблице DimCustomer , где LastName и BirthDate не соответствуют никаким записям в таблице ProspectiveBuyers .

  - Использует AdventureWorks
  
ВЫБЕРИТЕ a. LastName, a.Дата рождения
ОТ DimCustomer КАК
ГДЕ НЕ СУЩЕСТВУЕТ
(ВЫБРАТЬ *
    ОТ dbo.ProspectiveBuyer AS b
    ГДЕ (a.LastName = b.LastName) AND (a.BirthDate = b.BirthDate));
  

См. Также

Выражения (Transact-SQL)
Встроенные функции (Transact-SQL)
WHERE (Transact-SQL)

Как работают операторы SQL EXISTS?

Модель таблицы базы данных

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

Таблица student, является родительской, а таблица student_grade является дочерней, поскольку в ней есть столбец внешнего ключа student_id, ссылающийся на столбец первичного ключа id в таблице учеников.

Таблица студентов содержит следующие две записи:

  | id | first_name | last_name | admission_score |
| ---- | ------------ | ----------- | ----------------- |
| 1 | Алиса | Смит | 8. 95 |
| 2 | Боб | Джонсон | 8.75 |
  

И таблица student_grade хранит оценки, полученные учащимися:

  | id | class_name | сорт | student_id |
| ---- | ------------ | ------- | ------------ |
| 1 | Математика | 10 | 1 |
| 2 | Математика | 9,5 | 1 |
| 3 | Математика | 9,75 | 1 |
| 4 | Наука | 9,5 | 1 |
| 5 | Наука | 9 | 1 |
| 6 | Наука | 9.25 | 1 |
| 7 | Математика | 8.5 | 2 |
| 8 | Математика | 9.5 | 2 |
| 9 | Математика | 9 | 2 |
| 10 | Наука | 10 | 2 |
| 11 | Наука | 9,4 | 2 |
  

СУЩЕСТВУЕТ SQL

Допустим, мы хотим получить всех учеников, получивших 10 баллов по математике.

Если нас интересует только идентификатор студента, мы можем запустить такой запрос:

  ВЫБРАТЬ
    student_grade.student_id
ИЗ
    student_grade
КУДА
    student_grade.grade = 10 И
    student_grade.class_name = 'Математика'
СОРТИРОВАТЬ ПО
    student_grade.student_id
  

Но приложение заинтересовано в отображении полного имени ученика , а не только идентификатора, поэтому нам также нужна информация из таблицы student .

Чтобы отфильтровать записи учеников с 10 оценками по математике, мы можем использовать оператор EXISTS SQL, например:

  ВЫБРАТЬ
    id, first_name, last_name
ИЗ
    ученик
ГДЕ СУЩЕСТВУЕТ (
    ВЫБРАТЬ 1
    ИЗ
        student_grade
    КУДА
        student_grade.student_id = student.id И
        student_grade.grade = 10 И
        student_grade.class_name = 'Математика'
)
ЗАКАЗАТЬ ПО id
  

При выполнении вышеуказанного запроса мы видим, что выбрана только строка Алисы:

  | id | first_name | last_name |
| ---- | ------------ | ----------- |
| 1 | Алиса | Смит |
  

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

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

Внутренний подзапрос коррелирован, поскольку столбец student_id таблицы student_grade сопоставляется со столбцом id внешней таблицы student.

Как использовать SQL СУЩЕСТВУЕТ И НЕ СУЩЕСТВУЕТ SQL-функции?

Введение

Назначение операторов SQL «Существует» и «Не существует» — проверить наличие записей в подзапросе.Еще один похожий оператор — это предложение with, которое было введено в 1999 году для поддержки функций CTE (Common Table Expressions). Эти операторы предопределены в SQL и используются вместе с операторами UPDATE, DELETE или SELECT. Операторы SQL Exists и Not Exists следует использовать вместе, поскольку они не являются независимыми сами по себе.

Когда SQL Exists используется вместе с предложением Where, он проверяет наличие строк в подзапросе.

  • Если этот подзапрос содержит строку, он возвращает ИСТИНА.
  • Оператор Exists аналогичен оператору IN в SQL, и их вывод почти такой же, но синтаксис отличается.
  • Можно использовать оператор Exists с операторами UPDATE, DELETE или SELECT.

Читайте: Служба отчетов SQL Server: все, что вам нужно знать о параметризованных отчетах

Базовый синтаксис оператора SQL Exists приведен ниже.

  • Здесь вы должны указать имя столбца таблицы.
  • Выражения могут быть одной константой, переменной, скалярной функцией, именем столбца или частями SQL-запроса, который сравнивает значения и при необходимости выполняет арифметические вычисления.
  • Во второй строке кода вы должны добавить имя таблицы.
  • Последняя строка кода проверяет наличие одной или нескольких строк в подзапросе. Когда единственная строка удовлетворяет условию, она возвращает логическое значение True. Если совпадающих строк нет, возвращается логическое значение False, в противном случае вы также можете использовать оператор «Not Exists».

Чтение: Типы данных SQL для Oracle PL / SQL, MySQL, SQL Server и MS Access

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

Что такое подзапрос в SQL?

Подзапрос также называется внутренним запросом или вложенным запросом, который часто используется в других запросах. Подзапрос SQL может быть вложен в несколько операторов, таких как операторы SELECT, INSERT, UPDATE или DELETE и т. Д. В основном мы используем подзапрос в SQL с предложениями Where и Exists.Вот несколько основных правил использования подзапросов в SQL.

  • Каждый подзапрос следует заключать в круглые скобки.
  • Мы не можем использовать предложение Order By в подзапросе, пока мы не будем использовать предложение TOP.
  • Каждый подзапрос должен включать обычный оператор SELECT.
  • Предложения «Have», «Where», «Group By» могут использоваться необязательно в подзапросе.
  • Вы не можете использовать предложение Compute в подзапросе.
  • Подзапрос обычно вложен в предложения WHERE и Have или внешние операторы, такие как SELECT, INSERT, UPDATE, DELETE и т. Д.
  • SQL-сервер позволяет размещать подзапросы до 32 уровней. Он может варьироваться в зависимости от требований.

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

Изучите SQL Server самым простым способом

  • Учитесь на видео
  • Учитесь в любое время в любом месте
  • Карманный режим обучения
  • Доступна бесплатная электронная книга

Оператор SQL Exists с примером

Для более глубокого понимания оператора SQL «Exists» рассмотрим приведенный ниже пример. Есть две таблицы, в одной из которых хранятся сведения о сотрудниках, а во второй — ежемесячная заработная плата сотрудников. Давайте посмотрим, как использовать оператор «Exists» с этими двумя таблицами. В таблице вы можете увидеть три набора фиктивных данных. Здесь первая таблица хранит данные о сотрудниках, вторая таблица хранит зарплату, выплаченную сотрудникам, а третья таблица хранит результат для запроса «Существует». В третьей таблице вы можете увидеть, что всего возвращается пять записей, и каждая из них имеет уникальный идентификатор сотрудника, который сравнивается вместе для обеих таблиц.

Если есть какой-либо идентификатор, который не существует в обеих таблицах, тогда результатом будет ЛОЖЬ. Например, идентификатор «6» указан в первой таблице, но не упомянут во второй таблице, поэтому он не отображается в качестве выходных данных в таблице Exists.

Оператор «IN» в SQL

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

Прочтите: что такое ключ кандидата SQL? Разница между первичным ключом и ключом-кандидатом

Оператор «Не существует» в SQL

Оператор «Не существует» работает противоположно оператору «Существует». Это означает, что строки не возвращаются, когда выполняется оператор «Не существует». Давайте разберемся в концепции с помощью того же примера, приведенного ранее. Выход здесь будет противоположным. В приведенной выше таблице Exists эти две записи были опущены, и для извлечения этих двух строк следует использовать оператор Not Exists.Такой же вывод дает оператор «Not IN» в SQL, поскольку он работает противоположно оператору «IN».

Существуют операторы счетчика в SQL

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

Обучение и сертификация по SQL Server

  • Демонстрационный класс бесплатно
  • Промышленный эксперт в качестве вашего инструктора
  • Доступно по вашему расписанию
  • Служба поддержки клиентов

База данных SQL работает немного лучше при использовании оператора Exists вместо оператора Count из-за гораздо лучшей оценки количества элементов в середине плана выполнения.Каждый раз, когда вы хотите проверить строку на наличие, вы всегда должны использовать оператор Exists в этом случае. Кроме того, связанные с этим затраты с оператором Exists почти в 30 раз меньше, чем с оператором Count.

«Очевидно, что проверка существования выполняется быстрее, чем подсчет всех строк вместе, если вы действительно делаете что-то только для существования».

Рекомендации по производительности с Exists Operator

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

Чтение: различные типы ключей SQL: пример и использование

Причина в том, что оператор Exists следует принципу «по крайней мере найден» в запросах. Он устанавливается в значение ИСТИНА, если условию удовлетворяет даже одна строка. В некоторых случаях он останавливает выполнение в том же месте, где для результата устанавливается значение ИСТИНА.Однако вы должны использовать операторы сравнения с Exists, чтобы продолжить сканирование таблицы.

Заключение

На этом обсуждение мы подошли к концу блога. Здесь вы познакомитесь с основами оператора SQL Exists и узнаете, как его использовать с запросами SQL. Мы также обсудили один подробный пример для вашей справки, чтобы глубже понять концепцию. Но для практики этого оператора недостаточно одного примера.

Чтобы изучить несколько примеров SQL Exists, вам следует сразу же присоединиться к онлайн-программе сертификации SQL и быстро начать практиковать разные операторы.Это поможет вам практически выучить SQL и получить работу в области SQL с привлекательными пакетами заработной платы.

Зарегистрируйтесь на наш демо-класс сегодня, чтобы получить более подробную информацию!

Прочитано: 100 самых популярных вопросов и ответов на собеседовании по SQL

Обзор учебного пособия по SQL

Введение

Оператор и функции SQL Server

Ключи SQL Server

Запросы SQL Server

Дифференциация

Карьера

Интервью

Полезный ресурс

Учебник

Курс SQL Server
Предстоящие партии


Популярные курсы

AWS

  • AWS и основы Linux
  • Amazon Simple Storage Service
  • Эластичное вычислительное облако
  • Обзор баз данных и Amazon Route 53

Предстоящий класс

0 день 12 фев 2021

DevOps

  • Введение в DevOps
  • GIT и Maven
  • Дженкинс и Ansible
  • Докер и облачные вычисления

Предстоящий класс

0 день 12 фев 2021

Наука о данных

  • Введение в науку о данных
  • Обзор Hadoop и Spark
  • Python и введение в программирование на R
  • Машинное обучение

Предстоящий класс

21 день 05 мар. 2021

Hadoop

  • Архитектура, HDFS и MapReduce
  • Оболочка Unix и установка Apache Pig
  • Установка HIVE и пользовательские функции
  • Установка SQOOP и Hbase

Предстоящий класс

7 дней 19 фев 2021

Salesforce

  • Введение в конфигурацию Salesforce
  • Процессы безопасности и автоматизации
  • Облако продаж и обслуживания
  • Программирование Apex, SOQL и SOSL

Предстоящий класс

8 дней 20 фев 2021

QA

  • Введение и тестирование программного обеспечения
  • Жизненный цикл тестирования программного обеспечения
  • Автоматизация тестирования и тестирования API
  • Разработка фреймворка Selenium с использованием тестирования

Предстоящий класс

0 день 12 фев 2021

Бизнес-аналитик

  • BA и обзор заинтересованных сторон
  • BPMN, выявление требований
  • BA Инструменты и проектная документация
  • Анализ предприятия, Agile и Scrum

Предстоящий класс

0 день 12 фев 2021

MS SQL Server

  • Введение и запрос к базе данных
  • Программирование, индексы и системные функции
  • Процедуры разработки пакетов служб SSIS
  • Дизайн отчета SSRS

Предстоящий класс

7 дней 19 фев 2021

Python

  • Особенности Python
  • Редакторы Python и IDE
  • Типы данных и переменные
  • Операция с файлом Python

Предстоящий класс

8 дней 20 фев 2021

Искусственный интеллект

  • Компоненты AI
  • Категории машинного обучения
  • Рекуррентные нейронные сети
  • Рекуррентные нейронные сети

Предстоящий класс

15 дней 27 фев 2021

Машинное обучение

  • Введение в машинное обучение и Python
  • Машинное обучение: обучение с учителем
  • Машинное обучение: обучение без учителя

Предстоящий класс

28 дней 12 мар. 2021

Таблица

  • Знакомство с Tableau Desktop
  • Методы преобразования данных
  • Настройка сервера таблиц
  • Интеграция с R & Hadoop

Предстоящий класс

5 дней 17 фев 2021

— Выберите курс -SalesforceAzureQA TestingSQL ServerБизнес-аналитикHadoopAWSDevOpsНаука о данныхJavaЦифровой маркетингDotnetPMPSeleniumСтоит посетитьМашинное обучениеPythonOracle DBADАналитик данныхТаблицаauSixmaScrum MasterBlockchainИскусственный интеллект7AndroidCyber ​​SecurityVMware 9000

— Категория — СтатьяУчебникиВопросы для интервью

— Выберите время -На этой неделе, в этом месяце, в этом годуСамые популярные

Курс SQL Server
Предстоящие партии


Получать последние материалы и предложения по курсу SQL Server

SQL EXISTS Оператор

Оператор SQL EXISTS используется для ограничения количества строк, возвращаемых оператором SELECT. Оператор EXISTS в SQL проверяет наличие строк в подзапросе и, если они есть, возвращает TRUE, в противном случае — FALSE.

Синтаксис оператора SQL EXISTS

Базовый синтаксис оператора EXISTS в SQL Server можно записать как:

 SELECT [имена столбцов]
ОТ [Источник]
ГДЕ СУЩЕСТВУЕТ (написать подзапрос для проверки) 
  • Столбцы: Позволяет нам выбрать количество столбцов из таблиц. Это может быть Один или несколько.
  • Источник: Одна или несколько таблиц, присутствующих в базе данных.SQL JOINS используются для объединения нескольких таблиц.
  • Подзапрос: Здесь мы должны предоставить подзапрос. Если подзапрос возвращает истину, он вернет записи, в противном случае SQL Server не вернет никаких записей.

Для этой демонстрации EXISTS Operator мы собираемся использовать показанные ниже данные

Пример оператора SQL EXISTS 1

Следующий запрос оператора Exists найдет всех сотрудников, присутствующих в таблице сотрудников, у которых [Продажи] больше 1000

СОВЕТ: Прежде чем перейти к этому примеру оператора Sql Server Exists, я предлагаю вам обратиться к статье «Подзапросы SQL», чтобы понять проектирование подзапросов и анализ запросов.

 - Пример для оператора EXISTS SQL Server
ИСПОЛЬЗУЙТЕ [Учебное пособие по SQL]
ИДТИ
ВЫБЕРИТЕ EMP1. [EmpID]
      , EMP1. [Имя]
      , EMP1. [Фамилия]
      , EMP1. [Образование]
      , EMP1. [Профессия]
      , EMP1. [Годовой доход]
      , EMP1. [Продажи]
      , EMP1. [HireDate]
  ОТ [Сотрудник] AS EMP1
  ГДЕ СУЩЕСТВУЕТ (ВЫБРАТЬ * ОТ [Сотрудник] КАК EMP2
ГДЕ EMP1. [EmpID] = EMP2. [EmpID]
И [Продажи]> 1000
) 

Позвольте мне показать вам результат подзапроса

Позвольте мне изменить условие на Sales = 1000, что является ложным условием

 - Пример для оператора EXISTS SQL Server
ИСПОЛЬЗУЙТЕ [Учебное пособие по SQL]
ИДТИ
ВЫБЕРИТЕ EMP1.[EmpID]
      , EMP1. [Имя]
      , EMP1. [Фамилия]
      , EMP1. [Образование]
      , EMP1. [Профессия]
      , EMP1. [Годовой доход]
      , EMP1. [Продажи]
      , EMP1. [HireDate]
  ОТ [Сотрудник] AS EMP1
  ГДЕ СУЩЕСТВУЕТ (ВЫБРАТЬ * ОТ [Сотрудник] КАК EMP2
ГДЕ EMP1. [EmpID] = EMP2. [EmpID]
И [Продажи] = 1000
) 

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

EXISTS Пример оператора 2

Следующий запрос SQL существует для поиска всех сотрудников в таблице сотрудников, чья [профессия] равна Management

 - Пример для оператора EXISTS SQL Server
ИСПОЛЬЗУЙТЕ [Учебное пособие по SQL]
ИДТИ
ВЫБЕРИТЕ EMP1.[EmpID]
      , EMP1. [Имя]
      , EMP1. [Фамилия]
      , EMP1. [Образование]
      , EMP1. [Профессия]
      , EMP1. [Годовой доход]
      , EMP1. [Продажи]
      , EMP1. [HireDate]
  ОТ [Сотрудник] AS EMP1
  ГДЕ СУЩЕСТВУЕТ (ВЫБРАТЬ * ОТ [Сотрудник] КАК EMP2
ГДЕ EMP1. [EmpID] = EMP2. [EmpID]
И [Профессия] = "Менеджмент"
) 

EXISTS Пример оператора 3

Следующий запрос SQL существует оператор найдет всех сотрудников, присутствующих в таблице сотрудников, чья профессия — менеджмент, профессиональный или канцелярский.Здесь мы собираемся использовать оператор SQL IN внутри SubQuery

.

 - Пример для оператора EXISTS SQL Server
ИСПОЛЬЗУЙТЕ [Учебное пособие по SQL]
ИДТИ
ВЫБЕРИТЕ EMP1.  [EmpID]
      , EMP1. [Имя]
      , EMP1. [Фамилия]
      , EMP1. [Образование]
      , EMP1. [Профессия]
      , EMP1. [Годовой доход]
      , EMP1. [Продажи]
      , EMP1. [HireDate]
  ОТ [Сотрудник] AS EMP1
  ГДЕ СУЩЕСТВУЕТ (ВЫБРАТЬ * ОТ [Сотрудник] КАК EMP2
ГДЕ EMP1. [EmpID] = EMP2. [EmpID]
И [Профессия] IN («Менеджмент», «Профессиональный», «Канцелярский»)
) 

EXISTS Пример оператора 4

Вы можете спросить, почему я использую EMP1.[EmpID] = EMP2. [EmpID] внутри подзапроса. Итак, позвольте мне удалить эту строку и посмотреть

 - Пример для оператора EXISTS SQL Server
ИСПОЛЬЗУЙТЕ [Учебное пособие по SQL]
ИДТИ
ВЫБЕРИТЕ EMP1. [EmpID]
      , EMP1. [Имя]
      , EMP1. [Фамилия]
      , EMP1. [Образование]
      , EMP1. [Профессия]
      , EMP1. [Годовой доход]
      , EMP1. [Продажи]
      , EMP1. [HireDate]
  ОТ [Сотрудник] AS EMP1
  ГДЕ СУЩЕСТВУЕТ (ВЫБРАТЬ * ОТ [Сотрудник] КАК EMP2
ГДЕ [Профессия] IN («Менеджмент», «Профессиональный», «Канцелярский»)
) 

Как видно из приведенного ниже снимка экрана, этот SQL-запрос возвращает все записи, присутствующие в выбранной таблице. Потому что подзапрос возвращает ИСТИНА

Рассмотрите возможность использования [NOT] EXISTS вместо [NOT] IN с подзапросом (PE019)

  • Подсказка SQL
  • Анализ кода SQL

Фил Фактор объясняет, почему вы должны предпочесть использование [НЕ] СУЩЕСТВУЕТ, а не [НЕ] IN, при сравнении наборов данных с помощью подзапроса.Хотя существенного преимущества в производительности больше нет, использование NOT EXISTS позволит избежать непредвиденных результатов, когда исходные данные подзапроса содержат значения NULL.

Гостевой пост

Это гостевой пост от Фила Фактора. Фил Фактор (настоящее имя не разглашается для защиты виновных), также известный как Database Mole, имеет 30-летний опыт работы с приложениями, интенсивно использующими базы данных.

Несмотря на то, что однажды на выставке в начале 1980-х на него кричал разъяренный Билл Гейтс, он оставался абсолютно анонимным на протяжении всей своей карьеры.

Он является постоянным участником Simple Talk и SQLServerCentral .

Раньше логический оператор EXISTS был быстрее, чем IN, при сравнении наборов данных с помощью подзапроса. Например, в случаях, когда запрос должен был выполнить определенную задачу, но только если подзапрос вернул какие-либо строки, тогда при оценке WHERE [NOT] EXISTS (подзапрос) ядро ​​базы данных может прекратить поиск, как только найдет только одну row, тогда как WHERE [NOT] IN (подзапрос) будет всегда собирать все результаты подзапроса перед дальнейшей обработкой.

Однако оптимизатор запросов теперь обрабатывает EXISTS и IN одинаково, когда это возможно, поэтому вы вряд ли заметите какие-либо существенные различия в производительности. Тем не менее, вы должны быть осторожны при использовании оператора NOT IN, если исходные данные подзапроса содержат значения NULL. В таком случае вам следует рассмотреть возможность использования оператора NOT EXISTS вместо NOT IN или преобразовать оператор в левое внешнее соединение.

Рекомендация предпочитать использование [NOT] EXISTS перед [NOT] IN »включена в качестве правила анализа кода в запрос SQL (PE019).

Что работает лучше: EXISTS или IN….?

Существует множество способов устранения различий между двумя наборами данных, но два из наиболее распространенных — использование логического оператора EXISTS или IN . Представьте, что у нас есть две простые таблицы: одна со всеми общеупотребительными словами английского языка ( CommonWords, ), а другая со списком всех слов из «Дракулы» Брэма Стокера ( WordsInDracula ). Загрузка TestExistsAndIn включает сценарий для создания этих двух таблиц и заполнения каждой из связанных с ней текстовых файлов.Как правило, полезно иметь такие таблицы на вашем сервере песочницы для запуска тестов во время разработки, хотя книга, которую вы используете, — это ваш выбор!

Сколько слов в Дракуле не являются общеупотребительными? Предполагая, что в столбце CommonWords. Word нет значений NULL (подробнее об этом позже), следующие запросы вернут тот же результат (1555 слов) и будут иметь тот же план выполнения, который использует объединение слиянием . (Правое анти-полусоединение) между двумя столами.

—использование NOT IN

SELECT Count (*)

FROM dbo.WordsInDracula

WHERE word NOT IN (SELECT CommonWords.word FROM dbo.CommonWords);

—Использование NOT EXISTS

SELECT Count (*)

FROM dbo.WordsInDracula

WHERE NOT EXISTS

(SELECT * FROM dbo.CommonWords

WHERE CommonWords.word = WordsInDracula.слово);

Листинг 1

Короче говоря, оптимизатор SQL Server обрабатывает оба запроса одинаково, и они будут выполнять то же самое.

… или ЛЮБОЙ, КРОМЕ, INNER JOIN, OUTER JOIN или INTERSECT…?

А как насчет всех других возможных методов, таких как использование ANY , EXCEPT , INNER JOIN , OUTER JOIN или INTERSECT ? В листинге 2 показаны еще семь альтернатив, которые я мог легко придумать, хотя будут и другие.

1

2

3

4

5

6

7

8

9

10

11

12

13

140004

14

18

19

20

21

22

23

24

25

26

27

28

29

30

34

35

36

37

38

39

40

41

42

43

44

45

46

48

51

52

53

54

55

56

57

58

59

60

61

— использование ЛЮБОГО

SELECT Count (*)

FROM dbo.WordsInDracula

ГДЕ НЕТ (WordsInDracula.word = ЛЮБОЕ

(ВЫБЕРИТЕ слово

ИЗ общих слов));

— Правое соединение с полуслияниями

— с использованием EXCEPT

SELECT Count (*)

FROM

(

SELECT word

FROM dbo. WordsInDracula

EXCEPT 9000 word dbo.CommonWords

) AS JustTheUncommonOnes;

— Правое анти-полуслитое соединение

—использование ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯ

SELECT Count (*)

FROM dbo.WordsInDracula

ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ dbo.CommonWords

ON CommonWords.word = WordsinDracula.word

ГДЕ CommonWords.word IS NULL;

— правое внешнее объединение слиянием

— использование ПОЛНОГО ВНЕШНЕГО СОЕДИНЕНИЯ

SELECT Count (*)

FROM dbo.WordsInDracula

full OUTER JOIN dbo.CommonWords

ON CommonWords.word.word = WordsinDracula

ГДЕ CommonWords.word ЕСТЬ NULL;

—Полное внешнее соединение реализовано как соединение слиянием.

— использование пересечения для получения разницы

SELECT (SELECT Count (*) FROM WordsInDracula) -Count (*)

FROM

(

SELECT word

FROM dbo.WordsInDracula

correct ВЫБЕРИТЕ слово

ИЗ dbo. CommonWords

) AS JustTheUncommonOnes;

— внутреннее объединение слиянием

— использование синтаксиса FULL OUTER JOIN для получения разницы

SELECT Count (*) — (SELECT Count (*) FROM CommonWords)

FROM dbo.WordsInDracula

full OUTER JOIN dbo.CommonWords

ON CommonWords.word = WordsinDracula.word

— полное внешнее объединение слиянием

— использование синтаксиса INNER JOIN для получения разницы

SELECT (SELECT Count (*) FROM WordsinDracula) -Count (*)

FROM dbo.WordsInDracula

INNER JOIN dbo.CommonWords

ON CommonWords.word = WordsinDracula.word

— внутреннее объединение слиянием

Листинг 2

Испытательная привязь

Все девять запросов дают одинаковые результаты, но работает ли какой-либо один подход лучше? Давайте поместим их всех в простую систему тестирования, чтобы увидеть, сколько времени занимает каждая версия! Опять же, файл загрузки кода включает в себя код тестовой оснастки и все девять запросов.

Как показывают результаты, хотя запросы выглядят по-разному, обычно это просто «синтаксический сахар» для оптимизатора. Каким бы элегантным ни был ваш SQL, оптимизатор просто пожимает плечами и предлагает эффективный план его выполнения. Фактически, первые четыре используют один и тот же план выполнения «правильное противополу слияния», и все они занимают одинаковое количество времени.

Мы проверим вариации, запустив тест несколько раз. Запросы INTERSECT и INNER JOIN использовали внутреннее соединение слиянием и были близки.Два запроса FULL OUTER JOIN были немного медленнее, но это была близкая гонка.

Ловушка НЕ ​​В

Есть определенная нереальность в сравнении наборов с нулевыми значениями в них, но если это происходит в разгар повседневной отчетности базы данных, все может пойти очень плохо. Если у вас есть значение NULL в результате подзапроса или выражения, которое передается логическому оператору IN , он даст разумный ответ и будет таким же, как эквивалент EXISTS . Однако НЕ В ведет себя совершенно иначе.

Листинг 3 демонстрирует проблему. Мы вставляем три общих и три необычных слова в табличную переменную @someWord и хотим узнать количество общих слов, которых нет в нашей табличной переменной.

1

2

3

4

5

6

7

8

9

10

11

12

13

140004

14

18

19

20

21

22

23

24

25

26

27

28

29

30

34

35

36

37

38

39

40

41

42

43

44

45

46

48

51

52

53

54

55

56

57

УСТАНОВИТЬ БЕЗ СЧЕТА;

DECLARE @someWord TABLE

(

word NVARCHAR (35) NULL

);

INSERT INTO @someWord

(

word

)

— три общих слова

SELECT TOP 3

word

FROM dbo. общие слова

ORDER BY word DESC;

— три необычных слова

INSERT INTO @someWord

(

word

)

ЗНАЧЕНИЯ

(‘flibberty’),

(‘jibberty

),

b0004 (‘ jibberty

) ;

SELECT [НЕ СУЩЕСТВУЕТ без NULL] = COUNT (*)

FROM commonwords AS MyWords

WHERE NOT EXISTS

(

SELECT word FROM @someWord AS s WHERE s.word LIKE MyWords.слово

);

SELECT [NOT IN без NULL] = COUNT (*)

FROM commonwords AS MyWords

WHERE word NOT IN (

SELECT word FROM @someWord

);

—Вставить значение NULL

INSERT INTO @someWord

(

word

)

VALUES

(NULL);

SELECT [NOT EXISTS with NULL] = COUNT (*)

FROM commonwords AS MyWords

WHERE NOT EXISTS

(

SELECT word FROM @someWord AS s WHERE s.word LIKE MyWords.word

);

SELECT [NOT IN with NULL] = COUNT (*)

FROM commonwords AS MyWords

WHERE word NOT IN (

SELECT word FROM @someWord

);

Листинг 3.

Запрос NOT IN , прежде чем мы вставили NULL в какое-то слово @ , и оба запроса NOT EXISTS , все правильно говорят нам, что 60385 слов нет в нашей табличной переменной, потому что три есть, а всего существует 60388 общих слов.Однако, если подзапрос может вернуть NULL , то NOT IN вообще не возвращает строк.

NULL на самом деле означает «неизвестно», а не ничего, поэтому любое выражение, которое сравнивается со значением NULL , возвращает NULL или unknown.

Логически SQL Server оценивает подзапрос, заменяет его списком возвращаемых значений, а затем оценивает условие [НЕ] IN .Для варианта IN нашего запроса это не вызывает проблемы, потому что решает следующее:

ГДЕ word = ‘flibberty’ OR word = ‘jibberty’ OR word = ‘flob’

OR word = ‘zygotes’ OR word = ‘zygote’ OR word = ‘zydeco’

OR word = NULL;

Возвращает 3 строки для совпадений по словам «z…». Жало идет с НЕ В , что разрешает следующее:

ГДЕ слово <> ‘flibberty’ И слово <> ‘jibberty’ И слово <> ‘flob’

И слово <> ‘zygotes’ И слово <> ‘zygote’ И слово <> ‘zydeco’

И слово <> NULL;

Условие AND при сравнении с NULL оценивается как «неизвестно», и поэтому выражение всегда будет возвращать нулевые строки.Это не ошибка; это по дизайну. Вы можете возразить, что NULL нельзя допускать ни в одном столбце, где вы хотите использовать выражение NOT IN , но в нашей реальной рабочей жизни эти вещи могут закрасться в источники таблиц. Стоит быть осторожным. Итак, используйте вариант EXISTS или один из других, или всегда не забывайте включать предложение WHERE в условие IN , чтобы исключить NULL s.

Как использовать предложение EXISTS в SQL? Пример реального SQL-запроса с использованием EXISTS

Привет, ребята, вы, возможно, слышали о том, насколько полезно предложение EXISTS при написании сложных запросов. Тем не менее, в то же время я также видел, что многие программисты изо всех сил пытаются понять и использовать предложения EXISTS и NOT EXISTS при написании SQL-запросов. Если вы один из них, то вы попали в нужное место. Сегодня вы узнаете, как использовать предложение EXISTS в SQL, взяв реальный пример и превосходный

из LeetCode. Предположим, что на веб-сайте есть две таблицы, таблица

.

Чтобы решить эту проблему, вам нужно сначала подумать о данных. Например, если покупатель никогда ничего не заказывал, значит, для него не будет никакой записи в таблице «Заказы».Молодец, половина задачи сделана.

Теперь вторая половина: как проверить, есть ли запись для конкретного клиента? Здесь вам помогут предложения EXISTS и NOT EXISTS, и об этом вы узнаете из этой статьи.

На самом деле это тоже популярный вопрос на собеседовании по SQL, и вы, возможно, уже видели его, но если нет, это нормально. Этот вопрос не так популярен, как второй по величине запрос о зарплате, но он также является одним из часто задаваемых SQL-запросов на собеседовании по программированию; вы можете увидеть полный список здесь.

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

Но, если вы новичок в мире SQL, лучше начать с всеобъемлющего курса SQL, такого как курс The Complete SQL Bootcamp от Jose Portilla на Udemy. Это поможет вам изучать SQL лучше и быстрее, и такие статьи также будут иметь больше смысла, если у вас есть некоторые знания SQL за плечами.

Таблицы и данные SQL

Прежде чем рассматривать запрос, давайте посмотрим на схему, таблицы и данные, чтобы лучше понять проблему. У нас есть две таблицы «Клиенты» и «Заказы». Клиенты содержат два столбца: Id и Name. Идентификатор представляет собой числовой столбец, а имя — текстовый столбец, предположим, что это тип VARCHAR.

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

У нас четыре клиента с идентификаторами от 1 до 4. Наша вторая таблица, Заказы, содержит Id, который представляет собой уникальный идентификатор для заказа, и CustomerId, который представляет собой идентификатор клиента, который делает этот заказ. Если какой-либо Клиент разместит заказ, его идентификатор будет существовать в таблице заказов.

Таблица: Клиенты.

+ —- + ——- +
| Id | Имя |
+ —- + ——- +
| 1 | Джо |
| 2 | Генри |
| 3 | Сэм |
| 4 | Макс |
+ —- + ——- +

Таблица: Заказы.

+ —- + ———— +
| Id | CustomerId |
+ —- + ———— +
| 1 | 3 |
| 2 | 1 |
+ —- + ———— +

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

+ ———— +
| Заказчики |
+ ———— +
| Генри |
| Макс |
+ ———— +

Если вы ищете еще несколько SQL-задач, вы можете попробовать решить задачи, приведенные в классической книге Джо Селко « SQL-головоломки и ответы», 2-е издание . Одна из лучших книг для улучшения ваших навыков работы с SQL-запросами.

Решение для клиентов, которые никогда не заказывают

Одно из наиболее распространенных решений этой проблемы — использование предложения SQL JOIN. Вы можете использовать LEFT OUTER JOIN для решения этой проблемы, как показано ниже:

 SELECT C.Name FROM Customers C
LEFT JOIN Orders O ON C.Id = O.CustomerId
ГДЕ O.CustomerId - НУЛЬ 

Когда вы соединяете две таблицы в SQL с помощью LEFT OUTER JOIN, тогда будет создана большая таблица со значениями NULL в столбце, которых нет в другой таблице.

Например, большая таблица будет иметь четыре столбца C.Id, C.Name, O.Id и O.CustomerId, для клиентов, которые никогда ничего не заказывали, O.CustomerId будет NULL.

Многие программисты совершают ошибку, используя ! = в условии JOIN для решения этой проблемы, предполагая, что if = возвращает совпадающие строки, тогда! = Вернет те идентификаторы, которых нет в другой таблице. Так что остерегайтесь этого.

Если вам сложно понять, как присоединиться, я предлагаю вам взглянуть на отличный курс Хосе Портиллы по SQL The Complete SQL Bootcamp на Udemy.Его стиль преподавания потрясающий, и вы сразу поймете, как он присоединяется.

В любом случае, эта проблема на самом деле является отличным примером , как и когда использовать предложение EXISTS:

 SELECT C.Name FROM Customers C
ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ 1 ИЗ Orders O WHERE C.Id = O.CustomerId) 

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

Кстати, самое простое решение — использовать NOT IN Clause.

 ВЫБЕРИТЕ A. Имя от клиентов A
ГДЕ A.Id НЕ ВХОДИТ (ВЫБЕРИТЕ B.CustomerId из заказов B) 

Это все о том, как использовать предложение EXISTS в SQL для поиска всех клиентов, которые никогда не заказывали. Если вы хотите улучшить навыки работы с SQL-запросами, вы также можете решить задачи, описанные в классической книге Джо Селко «Загадки и ответы на SQL», 2-е издание. Одна из лучших книг с множеством сложных вопросов для проверки ваших навыков SQL, и если вам нужны онлайн-курсы для углубленного изучения SQL или заполнения пробелов в ваших знаниях SQL, следующие курсы — хорошее место для начала.

Дальнейшее обучение
Введение в SQL
SQL для новичков: анализ данных для начинающих
SQL-головоломки и ответы, 2-е издание

Другие связанные запросы SQL , вопросы интервью и статьи:

  • Как присоединиться к трем таблицы в одном SQL-запросе (решение)
  • Напишите запрос SQL, чтобы найти все имена таблиц в базе данных в MySQL (решение)
  • 5 курсов для изучения баз данных и SQL Better (курсы)
  • Написать SQL-запрос для копирования или резервного копирования таблицы в MySQL (решение)
  • Как найти повторяющиеся строки в таблице базы данных? (раствор)
  • 5 курсов для изучения баз данных Oracle и Microsoft SQL Server (курсы)
  • Реальная разница между предложениями WHERE и HAVING в SQL? (ответ)
  • Как перенести SQL-запросы с Oracle на SQL Server 2008? (ответ)
  • 5 лучших веб-сайтов для БЕСПЛАТНОГО изучения SQL в Интернете? (ресурс)
  • В чем разница между UNION и UNION ALL в SQL? (ответ)
  • Разница между Self и Equi Join в SQL? (ответ)
  • Лучшие курсы 5 для изучения базы данных MySQL для начинающих (курсы)
  • В чем разница между представлением и материализованным представлением в базе данных? (ответ)
  • Разница между кластеризованным и некластеризованным индексом в SQL? (ответ)
  • Разница между первичным ключом и ключом кандидата в таблице? (ответ)
  • 5 бесплатных курсов по изучению T-SQL и SQL Server для начинающих (курсы)
  • Разница между уникальным и первичным ключом в таблице? (ответ)
  • Разница между первичным и внешним ключом в таблице? (ответ)

Спасибо, что прочитали эту статью, если вам понравилась эта статья по SQL, поделитесь ею со своими друзьями и коллегами.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *