Для чего нужен APPLY

Tsql теория > Для чего нужен APPLY
31.05.2018 14:17:22



Статья:

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

Чтобы использовать APPLY, уровень совместимости базы данных должен быть не менее 90. 

Оператор CROSS APPLY возвращает только строки из внешней таблицы, которые создает результирующий набор из возвращающего табличное значение функции. Оператор OUTER APPLY возвращает и строки, которые формируют результирующий набор, и строки, которые этого не делают, со значениями NULL в столбцах, созданных возвращающей табличное значение функцией

Задача: Выбрать 10 последних заказов для каждого заказчика

Пускай имеем следующую простую структуру БД:

CREATE TABLE Customer
(
	CustomerID INT PRIMARY KEY,
	CustomerName NVARCHAR(30) NOT NULL
)

CREATE TABLE Nomenclature
(
	NomenclatureID INT PRIMARY KEY,
	NomenclatureName NVARCHAR(30) NOT NULL,
	Price MONEY  NOT NULL
)

CREATE TABLE Deal
(
	DealID INT IDENTITY(1, 1) PRIMARY KEY,
	CustomerID INT NOT NULL,
	NomenclatureID INT NOT NULL,
	[Count] DECIMAL(8,2) NOT NULL,
	DealDate DATETIME NOT NULL
)

С использованием APPLY SQL код :

SELECT 
	d.DealDate,
	c.CustomerName,
	n.NomenclatureName,
	n.Price,
	d.Count
FROM
	Customer c 
	OUTER APPLY (SELECT TOP 10 d1.* FROM Deal d1 Where d1.CustomerID = c.CustomerID ORDER BY d1.DealDate DESC) d
	INNER JOIN Nomenclature n ON
		n.NomenclatureID = d.NomenclatureID
ORDER BY c.CustomerName, d.DealDate DESC