- •Язык sql Выбор данных (оператор select)
- •Предложение group by (применение агрегатных функций)
- •Предложение having (условия обработки сформированных групп)
- •Порядок обработки предложений where, group by и having
- •Соединение
- •Вывод итоговых значений
- •Вложенные запросы (подзапросы)
- •Операторы манипулирования данными (dml) с подзапросами.
- •Понятие представления. Операции создания представлений.
- •Распределенные запросы
Язык sql Выбор данных (оператор select)
Оператор SELECT – один из наиболее важных и самых распространенных операторов SQL. Он позволяет производить выборки данных из таблиц и преобразовывать к нужному виду полученные результаты. Будучи очень мощным, он способен выполнять действия, эквивалентные операторам реляционной алгебры, причем в пределах единственной выполняемой команды. При его помощи можно реализовать сложные условия отбора данных из различных таблиц.
Оператор SELECT – средство, которое полностью абстрагировано от вопросов представления данных, что помогает сконцентрировать внимание на проблемах доступа к данным. Примеры его использования наглядно демонстрируют один из основополагающих принципов больших (промышленных) СУБД: средства хранения данных и доступа к ним отделены от средств представления данных. Операции над данными производятся в масштабе наборов данных, а не отдельных записей.
Запрос — это некоторый алгоритм решения конкретной задачи, которую мы формулируем заранее на естественном языке. Мощность языка SQL и состоит в том, что он позволяет одним предложением сформулировать ответы на достаточно сложные запросы, для реализации которых на традиционных языках понадобилось бы писать большую программу.
Результат запроса представляет собой таблицу.
Оператор SELECT имеет следующий формат:1
SELECT [ALL | DISTINCT ] [TOP expression [PERCENT] [ WITH TIES ] ]
{*|[имя_столбца
[AS новое_имя]]} [,...n]
FROM имя_таблицы [[AS] псевдоним] [,...n]
[WHERE <условие_поиска>]
[GROUP BY имя_столбца [,...n]]
[HAVING <критерии выбора групп>]
[ORDER BY имя_столбца [,...n]]
Обработка элементов оператора SELECT выполняется в следующей последовательности:
FROM – определяются имена используемых таблиц;
WHERE – выполняется фильтрация строк объекта в соответствии с заданными условиями;
GROUP BY – образуются группы строк, имеющих одно и то же значение в указанном столбце;
HAVING – фильтруются группы строк объекта в соответствии с указанным условием;
SELECT – устанавливается, какие столбцы должны присутствовать в выходных данных;
ORDER BY – определяется упорядоченность результатов выполнения операторов.
Параметры оператора:
Оператор SELECT определяет поля (столбцы), которые будут входить в результат выполнения запроса. В списке они разделяются запятыми и приводятся в такой очередности, в какой должны быть представлены в результате запроса.
Если используется имя поля, содержащее пробелы или разделители, его следует заключить в квадратные скобки.
Символом * можно выбрать все поля.
При наличии одноименных полей в разных таблицах в списке полей используется полная спецификация поля, т.е. Имя_таблицы.Имя_поля.
ALL. Чтобы обеспечить совместимость со стандартом SQL-92 и другими реализациями Microsoft SQL Server, предусмотрено ключевое слово ALL, позволяющее явно запросить все строки. Однако указывать его нет необходимости, потому что оно действует по умолчанию.
DISTINCT. Результат выполнения запроса может содержать дублирующиеся значения, поскольку в отличие от операций реляционной алгебры оператор SELECT не исключает повторяющихся значений при выполнении выборки данных.
Ключевое слово DISTINCT позволяет удалить повторяющиеся строки из результатов, возвращенных инструкцией SELECT. Если ключевое слово DISTINCT не указано, возвращаются все строки, в том числе повторяющиеся.
Если указано ключевое слово DISTINCT, значения NULL считаются повторяющимися. Если ключевое слово DISTINCT включено в инструкцию SELECT, в результат войдет только одно значение NULL независимо от того, сколько их на самом деле.
Причиной ограничения в применении DISTINCT является то обстоятельство, что его использование может резко замедлить выполнение запросов.
TOP в операторе SELECT
TOP-указывает на то, что будет возвращен только первый набор строк из результата запроса. Набор строк может быть либо числом, либо процентом. Предложение TOP может быть использовано в инструкциях SELECT, INSERT, UPDATE и DELETE.
expression - числовое выражение, которое задает количество возвращаемых строк. Аргумент expression прямо преобразуется в значение типа float, если указан PERCENT. В противном случае преобразуется в тип bigint.
Примечание: Разделение круглыми скобками в аргументе expression параметра TOP требуется в инструкциях INSERT, UPDATE и DELETE.
В следующем примере столбец VacationHours в таблице Employee обновляется на 25% для 10 произвольных строк.
USE AdventureWorks;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO
В целях обратной совместимости использование TOP expression без скобок в инструкции SELECT поддерживается, но не рекомендуется к использованию.
Если запрос включает предложение ORDER BY, возвращаются первые expression строк или expression процентов строк, отсортированных посредством предложения ORDER BY. Если запрос не содержит предложение ORDER BY, порядок строк будет произвольным.
PERCENT - указывает на то, что запрос возвращает только первые expression процентов строк из результирующего набора.
WITH TIES - указывает на то, что будут возвращены дополнительные строки из основного результирующего набора с тем же значением в столбцах ORDER BY, которые появляются как последние из TOP n (PERCENT) строк.
Пример. Следующий пример для получения 10 работников, перечисленных в таблице dbo.Employee базы данных AdventureWorks (не задается ORDER BY).
USE AdventureWorks ;
GO
SELECT TOP(10)*
FROM HumanResources.Employee;
GO
Пример. Следующий пример для получения 10 самых молодых работников, перечисленных в таблице dbo.Employee базы данных AdventureWorks (задается ORDER BY по полю BirthDate в порядке убывания).
USE AdventureWorks ;
GO
SELECT TOP(10)*
FROM HumanResources.Employee
ORDER BY BirthDate DESC
Пример. Следующий пример извлекает первые 10 работников с наибольшей зарплатой и возвращает их в порядке убывания базовой ставки зарплаты. Указание параметра WITH TIES обеспечивает, что все работники с зарплатой, равной минимальной возвращенной зарплате, включены в результирующий набор, даже если это приведет к превышению ограничения в 10 записей.
USE AdventureWorks ;
GO
SELECT TOP(10) WITH TIES
c.FirstName, c.LastName, e.Title, e.Gender, r.Rate
FROM Person.Contact c
INNER JOIN HumanResources.Employee e
ON c.ContactID = e.ContactID
INNER JOIN HumanResources.EmployeePayHistory r
ON r.EmployeeID = e.EmployeeID
ORDER BY Rate DESC;
Обратите внимание, что выдается 11 записей!!!!!!
Предложение FROM задает имена таблиц, которые содержат поля, перечисленные в операторе SELECT.
Необязательный параметр псевдонима ([AS новое_имя]]} [,...n]
В части FROM оператора SELECT допустимо применять синонимы к именам таблицы, если при формировании запроса нам требуется более чем один экземпляр некоторого отношения.
FROM имя_таблицы [[AS] псевдоним] [,...n]), устанавливаемое для имени поля и/или таблицы (обратите внимание, что для таблицы можно не указывать AS).
Поэтому часть FROM может выглядеть следующим образом:
FROM R1 AS A, R1 AS B
или
FROM R1 A, R1 B;
оба выражения эквивалентны и рассматриваются как применения оператора SELECT к двум экземплярам таблицы R1.
Для более удобного чтения лучше использовать ключевое слово AS.
Только два предложения SELECT и FROM являются обязательными.
Пример. Выбрать все поля из таблицы Клиент.
SELECT * FROM Клиент
Пример. Выбрать список всех фирм.
SELECT Клиент.Фирма FROM Клиент
Пример.
SELECT DISTINCT Клиент.Фирма -- удаляются повторяющиеся строки
FROM Клиент
Предложение WHERE определяет, какие блоки данных из приведенных в списке FROM таблиц появятся в результате запроса.
За ключевым словом WHERE следует перечень условий поиска, определяющих те строки, которые должны быть выбраны при выполнении запроса. Существует пять основных типов условий поиска (или предикатов):
Сравнение: сравниваются результаты вычисления одного выражения с результатами вычисления другого.
Диапазон: проверяется, попадает ли результат вычисления выражения в заданный диапазон значений.
Принадлежность множеству: проверяется, принадлежит ли результат вычислений выражения заданному множеству значений.
Соответствие шаблону: проверяется, отвечает ли некоторое строковое значение заданному шаблону.
Значение NULL: проверяется, содержит ли данный столбец определитель NULL (неизвестное значение).
Сравнение
В языке SQL можно использовать следующие операторы сравнения: = – равенство; < – меньше; > – больше; <= – меньше или равно; >= – больше или равно; <> – не равно.
Пример.
SELECT * FROM Сделка
WHERE Количество>20
Более сложные предикаты могут быть построены с помощью логических операторов AND, OR или NOT, а также скобок, используемых для определения порядка вычисления выражения.
Вычисление выражения в условиях выполняется по следующим правилам:
Выражение вычисляется слева направо.
Первыми вычисляются подвыражения в скобках.
Операторы NOT выполняются до выполнения операторов AND и OR.
Операторы AND выполняются до выполнения операторов OR.
Для устранения любой возможной неоднозначности рекомендуется использовать скобки.
Пример. Вывести список товаров, цена которых больше или равна 100 и меньше или равна 150.
SELECT Название, Цена
FROM Товар
WHERE Цена>=100 And Цена<=150
Пример. Вывести список клиентов из Москвы или из Самары.
SELECT Фамилия, ГородКлиента
FROM Клиент
WHERE ГородКлиента=’Москва’ Or
ГородКлиента=’Самара’
Диапазон
Оператор BETWEEN используется для поиска значения внутри некоторого интервала, определяемого своими минимальным и максимальным значениями. При этом указанные значения включаются в условие поиска.
Пример. Вывести список товаров, цена которых лежит в диапазоне от 100 до 150 (запрос эквивалентен примеру выше).
SELECT Название, Цена
FROM Товар
WHERE Цена Between 100 And 150
Можно использовать отрицание NOT BETWEEN (проверяемое значение находится вне границ заданного диапазона).
Пример. Вывести список товаров, цена которых не лежит в диапазоне от 100 до 150.
SELECT Товар.Название, Товар.Цена
FROM Товар
WHERE Товар.Цена Not Between 100 And 150
Или (что эквивалентно)
SELECT Товар.Название, Товар.Цена
FROM Товар
WHERE (Товар.Цена<100) OR (Товар.Цена>150)
Принадлежность множеству
Оператор IN используется для сравнения некоторого значения со списком заданных значений, при этом проверяется, соответствует ли результат вычисления выражения одному из значений в предоставленном списке. При помощи оператора IN может быть достигнут тот же результат, что и в случае применения оператора OR, однако оператор IN выполняется быстрее.
Пример. Вывести список клиентов из Москвы или из Самары
SELECT Фамилия, ГородКлиента
FROM Клиент
WHERE ГородКлиента IN (‘Москва’, ‘Самара’)
NOT IN используется для отбора любых значений, кроме тех, которые указаны в представленном списке.
Пример. Вывести список клиентов, проживающих не в Москве и не в Самаре.
SELECT Фамилия, ГородКлиента
FROM Клиент
WHERE ГородКлиента
Not IN (‘Москва’,’Самара’)
Соответствие шаблону
С помощью оператора LIKE можно выполнять сравнение выражения с заданным шаблоном, в котором допускается использование символов-заменителей:
Символ % – вместо этого символа может быть подставлено любое количество произвольных символов.
Символ _ заменяет один символ строки.
[] – вместо символа строки будет подставлен один из возможных символов, указанный в этих ограничителях.
[^] – вместо соответствующего символа строки будут подставлены все символы, кроме указанных в ограничителях.
Пример. Найти клиентов, у которых в номере телефона вторая цифра – 4.
SELECT Клиент.Фамилия, Клиент.Телефон
FROM Клиент
WHERE Клиент.Телефон Like ‘_4%’
Пример. Найти клиентов, у которых в номере телефона вторая цифра – 2 или 4.
SELECT Клиент.Фамилия, Клиент.Телефон
FROM Клиент
WHERE Клиент.Телефон Like ‘_[24]%’
Пример. Найти клиентов, у которых в номере телефона вторая цифра 2, 3 или 4.
SELECT Клиент.Фамилия, Клиент.Телефон
FROM Клиент
WHERE Клиент.Телефон Like ‘_[2-4]%’
Пример. Найти клиентов, у которых в фамилии встречается слог "ро".
SELECT Клиент.Фамилия
FROM Клиент
WHERE Клиент.Фамилия Like ‘%ро%’
Пример. Найти фамилии, начинающиеся на буквы вне диапазона от A до M:
SELECT au_lname FROM authors
WHERE au_lname LIKE ‘[^A-M]%’
Значение NULL
Неопределенное значение интерпретируется в реляционной модели как значение, неизвестное на данный момент времени. NULL – это не то же самое, что знак пробела (пробел – допустимый символ) или ноль (0 – допустимое число). NULL отличается и от строки нулевой длины (пустой строки). Это значение при появлении дополнительной информации в любой момент времени может быть заменено на некоторое конкретное значение.
Оператор IS NULL используется для сравнения текущего значения с NULL – специальным значением, указывающим на отсутствие любого значения.
При сравнении неопределенных значений не действуют стандартные правила сравнения: одно неопределенное значение никогда не считается равным другому неопределенному значению. Для выявления равенства значения некоторого атрибута неопределенному применяют специальные стандартные предикаты:
<имя атрибута>IS NULL и <имя атрибута> IS NOT NULL.
Если в данном кортеже (в данной строке) указанный атрибут имеет неопределенное значение, то предикат IS NULL принимает значение "Истина" (TRUE), а предикат IS NOT NULL — "Ложь" (FALSE), в противном случае предикат IS NULL принимает значение "Ложь", а предикат IS NOT NULL принимает значение "Истина".
Введение Null-значений вызвало необходимость модификации классической двузначной логики и превращения ее в трехзначную. Все логические операции, производимые с неопределенными значениями, подчиняются этой логике в соответствии с заданной таблицей истинности:
-
A
B
Not A
A B
A B
TRUE
TRUE
FALSE
TRUE
TRUE
TRUE
FALSE
FALSE
FALSE
TRUE
TRUE
Null
FALSE
Null
TRUE
FALSE
TRUE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
Null
TRUE
FALSE
Null
Null
TRUE
Null
Null
TRUE
Null
FALSE
Null
FALSE
Null
Null
Null
Null
Null
Null
В условиях поиска могут быть использованы все рассмотренные выше предикаты.
Пример. Найти сотрудников, у которых нет телефона (поле Телефон не содержит никакого значения).
SELECT Фамилия, Телефон
FROM Клиент
WHERE Телефон Is Null
IS NOT NULL используется для проверки присутствия значения в поле.
Пример. Выборка сотрудников, у которых есть телефон (поле Телефон содержит какое-либо значение).
SELECT Клиент.Фамилия, Клиент.Телефон
FROM Клиент
WHERE Клиент.Телефон Is Not Null
Общие правила использования выражений.
Выражение - сочетание символов и операторов, используемое компонентом SQL Server Database Engine для вычисления одиночного значения данных. Отдельные константы, переменные, столбцы и скалярные функции являются примерами простых выражений. Для соединения двух и более простых выражений в одно сложное используются операторы.
Синтаксис
{ constant | scalar_function | [ table_name. ] column | variable
| ( expression ) | ( scalar_subquery )
| { unary_operator } expression
| expression { binary_operator } expression }
Аргументы:
-
Ключ
Определение
constant
Символ, представляющий одно конкретное значение данных.
scalar_function
Элемент синтаксиса языка Transact-SQL, который предоставляет определенную службу и возвращает одиночное значение. Аргумент scalar_function может быть встроенной скалярной функцией, такой как SUM, GETDATE или CAST, либо пользовательской скалярной функцией.
[ table_name. ]
Имя или псевдоним таблицы.
column
Имя столбца. Только имя столбца используется в выражении.
variable
Имя переменной или параметр.
( expression )
Любое допустимое выражение из определенных в этом разделе. Скобки являются операторами группировки, гарантирующими, что все операторы выражения внутри скобок будут выполнены, прежде чем результирующее выражение будет объединено с другим.
( scalar_subquery )
Вложенный запрос, возвращающий одиночное значение.
{ unary_operator }
Оператор, имеющий только один числовой операнд.
{ binary_operator }
Оператор, определяющий способ, которым два выражения объединяются для получения одиночного результата. Аргумент binary_operator может быть арифметическим, логическим, битовым или унарным оператором, а также оператором присвоения (=), сравнения или оператором сцепления строк (+).
Замечания:
Два выражения можно объединить каким-либо оператором, если оба они содержат данные типов, поддерживаемых оператором, и выполняется хотя бы одно из следующих условий.
Выражения содержат данные одинаковых типов.
Тип данных с более низким приоритетом может быть неявно преобразован в тип данных с более высоким приоритетом.
Если выражения не удовлетворяют этим условиям, функция CAST или CONVERT явным образом преобразует тип данных с более низким приоритетом или в тип данных с более высоким приоритетом, или к промежуточному типу данных, который затем может быть неявно преобразован в тип данных с более высоким приоритетом. CAST и CONVERT будут рассмотрены позднее.
Если неявное или явное преобразование не поддерживается, эти два выражения объединить невозможно.
Если оператор связывает два выражения различных типов данных, то по правилам приоритета типов данных определяется, какой тип данных имеет меньший приоритет и будет преобразован в тип данных с большим приоритетом.
Если неявное преобразование не поддерживается, возвращается ошибка.
Если оба операнда выражения имеют одинаковый тип данных, результат операции будет иметь тот же тип данных.
В SQL Server 2005 используется следующий приоритет типов данных (последовательно уменьшается от 1 и далее):
определяемые пользователем типы данных (высший приоритет);
sql_variant;
xml;
datetime;
smalldatetime;
float;
real;
decimal;
money;
smallmoney;
bigint;
int;
smallint;
tinyint;
bit;
ntext;
text;
image;
timestamp;
uniqueidentifier;
nvarchar (включая nvarchar(max))
nchar;
varchar (включая varchar(max))
char;
varbinary (включая varbinary(max))
binary (низший приоритет)
Оператор присваивания.
Знак равенства (=) является единственным оператором присваивания в языке Transact-SQL.
Оператор присваивания может также использоваться для установления связи между заголовком столбца и выражением, которое определяет значение для столбца.
Следующий пример отображает заголовки столбцов FirstColumnHeading и SecondColumnHeading. Строка xyz выводится в заголовке столбца FirstColumnHeading для всех строк. Затем все коды продуктов из таблицы Product перечисляются в заголовке столбца SecondColumnHeading.
USE AdventureWorks;
GO
SELECT FirstColumnHeading = 'xyz',
SecondColumnHeading = ProductID
FROM Production.Product;
GO
Результат:
Арифметические операторы.
-
Оператор
Значение
+ (Сложение)
Сложение
- (Вычитание)
Вычитание
* (Умножение)
Умножение
/ (Деление)
Деление
% (Остаток)
Возвращает целочисленный остаток при делении. Например, 12 % 5 = 2, поскольку остаток от деления 12 на 5 равен 2.
Обратите внимание: возведение в степень не определено! Используется функция.
Пример:
SELECT orderid, productid, qty, unitprice, discount,
qty * unitprice * (1 - discount) AS val
FROM Sales.OrderDetails;
Битовые операторы.
Побитовые операторы выполняют побитовые действия над двумя выражениями с любым типом данных, относящимся к категории целочисленных типов данных.
-
Оператор
Значение
& (Побитовый оператор И)
Побитовый оператор И (два операнда).
| (Побитовый оператор ИЛИ)
Побитовый оператор ИЛИ (два операнда).
^ (Побитовый оператор, исключающий ИЛИ)
Побитовый оператор, исключающий ИЛИ (два операнда).
Операнды побитовых операторов могут принадлежать к любому из целочисленных типов данных или к категории типов данных «двоичная строка» (кроме типа данных image), однако оба операнда не могут относиться к типам данных из категории «двоичная строка». Следующая таблица показывает поддерживаемые типы данных операндов.
-
Левый операнд
Правый операнд
binary
int, smallint или tinyint
bit
int, smallint, tinyint или bit
int
int, smallint, tinyint, binary или varbinary
smallint
int, smallint, tinyint, binary или varbinary
tinyint
int, smallint, tinyint, binary или varbinary
varbinary
int, smallint или tinyint
Пример: создается таблица с помощью типа данных int для хранения значений, и два значения вставляются в одну строку.
CREATE TABLE bitwise
(
a_int_value int NOT NULL,
b_int_value int NOT NULL
);
GO
INSERT bitwise VALUES (170, 75);
GO
В этом запросе побитовое И выполняется на столбцах a_int_value и b_int_value.
SELECT a_int_value & b_int_value
FROM bitwise;
Результат:
10
Двоичное представление числа 170 (a_int_value или A) — 0000 0000 1010 1010. Двоичное представление числа 75 (b_int_value или B) — 0000 0000 0100 1011. Выполнение побитовой операции И на этих двух значениях дает двоичный результат 0000 0000 0000 1010, который имеет десятичное значение 10.
(A & B)
0000 0000 1010 1010
0000 0000 0100 1011
-------------------
0000 0000 0000 1010
В этом запросе выполняется операция побитового исключающего ИЛИ выполняется на столбцах a_int_value и b_int_value.
SELECT a_int_value ^ b_int_value
FROM bitwise;
Результат:
225
(A ^ B)
0000 0000 1010 1010
0000 0000 0100 1011
-------------------
0000 0000 1110 0001
При выполнении операции побитового исключающего ИЛИ над этими двумя значениями получается двоичный результат 0000 0000 1110 0001, который является десятичным числом 225.
Операторы сравнения.
Операторы сравнения позволяют проверить, одинаковы ли два выражения. Операторы сравнения можно применять ко всем выражениям, за исключением выражений типов text, ntext и image.
-
Оператор
Значение
= (равно)
Равно
> (больше)
Больше
< (меньше)
Меньше
>= (больше или равно)
Больше или равно
<= (меньше или равно)
Меньше или равно
<> (не равно)
Не равно
!= (не равно)
Не равно (не входит в стандарт SQL-92)
!< (не меньше)
Не меньше (не входит в стандарт SQL-92)
!> (не больше)
Не больше (не входит в стандарт SQL-92)
Логические операторы
Логические операторы проверяют истину некоторого условия. Логические операторы, например оператор сравнения, возвращают значение типа Boolean: TRUE, FALSE или UNKNOWN.
-
Оператор
Значение
ALL
TRUE, если все сравнения в наборе равны TRUE.
AND
TRUE, если оба выражения типа Boolean равны TRUE.
ANY
TRUE, если любое из сравнений в наборе равно TRUE.
BETWEEN
TRUE, если операнд принадлежит указанному диапазону.
EXISTS
TRUE, если вложенный запрос возвращает как минимум одну строку.
IN
TRUE, если операнд содержится в заданном списке выражений.
LIKE
TRUE, если оператор удовлетворяет шаблону.
NOT
Меняет значение оператора типа Boolean на противоположное.
OR
TRUE, если одно из выражений типа Boolean равно TRUE.
SOME
TRUE, если некоторые из сравнений в наборе равны TRUE.
Пример:
SELECT orderid, empid, orderdate
FROM Sales.Orders
WHERE orderdate >= '20080101'
AND empid IN(1, 3, 5);
Оператор сцепления строк.
Знак «плюс» (+) является оператором сцепления строк. Все остальные операции со строками выполняются с помощью строковых функций.
Унарные операторы.
Унарные операторы выполняют операцию только на одном выражении любого типа данных из категории числовых типов данных.
-
Оператор
Значение
+ (знак «плюс»)
Числовое значение положительно.
- (знак «минус»)
Числовое значение отрицательно.
~ (побитовое НЕ)
Возвращает поразрядное дополнение числа.
Операторы + (знак «плюс») и - (знак «минус») можно использовать в любом выражении любого типа данных из категории числовых типов данных. Оператор ~ (побитовое НЕ) можно использовать только в выражениях любого типа данных из категории целочисленных типов данных.
Порядок выполнения операций.
Скобки
(Умножение), / (Деление), % (Остаток от деления нацело)
+(положительный операнд), - (отрицательный), + (сложение), + (сцепление), - (вычитание)
Операции сравнения
NOT
AND
BETWEEN IN LIKE OR
=(присваивание)
Пример:
SELECT orderid, custid, empid, orderdate
FROM Sales.Orders
WHERE
custid = 1
AND empid IN(1, 3, 5)
OR custid = 85
AND empid IN(2, 4, 6)
Скобки улучшают читаемость программного кода.
Пример эквивалентен предыдущему:
SELECT orderid, custid, empid, orderdate
FROM Sales.Orders
WHERE
( custid = 1
AND empid IN(1, 3, 5) )
OR
( custid = 85
AND empid IN(2, 4, 6) )