USE [AdventureWorks2019];

--Создать синоним

CREATE SYNONYM
	P1 FOR [Person].[Person];

--Сделать выборку из исходной таблицы

SELECT
	*
FROM
	[Person].[Person];

--Сделать выборку из исходной таблицы, обращаясь к её синониму

SELECT
	*
FROM
	P1;

--Удалить созданный синоним

DROP SYNONYM
	P1;

--создаем таблицу с кандидатами
CREATE TABLE candidates ( 
	candname VARCHAR(10) NOT NULL, 
	gender CHAR(1) NOT NULL CONSTRAINT chk_gender CHECK (gender IN ('F', 'M')) 
  );

--наполняем её данными
INSERT INTO
	dbo.candidates 
VALUES
	('Neil', 'M'),
	('Trevor', 'M'), 
	('Terresa', 'F'),
	('Mary', 'F');

--делаем выборку из нашей таблицы
SELECT
	*
FROM
	dbo.candidates;

--строим нашу таблицу рекомендаций для свиданий

SELECT
	C1.candname, 
    C2.candname 
FROM
	dbo.candidates AS C1 
CROSS JOIN
	dbo.candidates AS C2
WHERE
	C1.candname <> C2.candname AND
	C1.gender <> C2.gender AND
	C1.gender = 'M';

--TOP фильтры

--Вывести все данные из нашей таблицы

SELECT
	Name,
	ProductNumber,
	StandardCost
FROM
	Production.Product
ORDER BY
	StandardCost DESC;

--Вывести первые 20 значений

SELECT
	TOP 20 Name,
	ProductNumber,
	StandardCost
FROM
	Production.Product
ORDER BY
	StandardCost DESC;

--Вывести первые 20 значений с повторами значений из столбца в ORDER BY

SELECT
	TOP 20 WITH TIES Name
	ProductNumber,
	StandardCost
FROM
	Production.Product
ORDER BY
	StandardCost DESC;

--Вывести 20% значений из нашей исходной таблицы

SELECT
	TOP 20 PERCENT Name,
	ProductNumber,
	StandardCost
FROM
	Production.Product
ORDER BY
	StandardCost DESC;

--Пропустить первые 20 строк и вывести следующие 20 строк из нашей таблицы

SELECT
	Name,
	ProductNumber,
	StandardCost
FROM
	Production.Product
ORDER BY
	StandardCost DESC
OFFSET
	20 ROWS
FETCH
	NEXT 20 ROWS ONLY;

--Пропустить 0 строк и вывести следующие 20 строк из нашей таблицы

SELECT
	Name,
	ProductNumber,
	StandardCost
FROM
	Production.Product
ORDER BY
	StandardCost DESC
OFFSET
	0 ROWS
FETCH
	NEXT 20 ROWS ONLY;

--Пропустить первые 20 строк и вывести все оставшиеся данные из нашей таблицы из нашей таблицы

SELECT
	Name,
	ProductNumber,
	StandardCost
FROM
	Production.Product
ORDER BY
	StandardCost DESC
OFFSET
	20 ROWS;

SELECT
	PI.ProductID,
	PI.LocationID,
	PI.Quantity
FROM
	Production.ProductInventory AS PI;

SELECT TOP 3
	PI.ProductID,
	PI.LocationID,
	PI.Quantity
FROM
	Production.ProductInventory AS PI
ORDER BY
	PI.Quantity DESC;

SELECT
	P.ProductID,
	P.Name
FROM
  Production.Product AS P;

--CROSS APPLY

SELECT
	P.ProductID,
	P.Name,
	A.LocationID,
	A.Quantity
FROM
  Production.Product AS P
CROSS APPLY
	(SELECT TOP 3
		PI.ProductID,
		PI.LocationID,
		PI.Quantity
	FROM
		Production.ProductInventory AS PI
	WHERE
		PI.ProductID = P.ProductID
	ORDER BY
		PI.Quantity DESC) AS A
ORDER BY
	P.ProductID;

--OUTER APPLY

SELECT
	P.ProductID,
	P.Name,
	A.LocationID,
	A.Quantity
FROM
  Production.Product AS P
OUTER APPLY
	(SELECT TOP 3
		PI.ProductID,
		PI.LocationID,
		PI.Quantity
	FROM
		Production.ProductInventory AS PI
	WHERE
		PI.ProductID = P.ProductID
	ORDER BY
		PI.Quantity DESC) AS A
ORDER BY
	P.ProductID;

--создадим новую базу данных
CREATE DATABASE
	University;

--переключимся на неё
USE
	University;

--создадим в новой базе данных таблицу

CREATE TABLE Class
(
	ID INT PRIMARY KEY IDENTITY,
	StudentName VARCHAR(50),
	Course VARCHAR(50),
	Score INT
);

--наполним эту талицу тестовыми данными

INSERT INTO
	dbo.Class
VALUES
	('Sally', 'English', 95),
	('Sally', 'History', 82),
	('Edward', 'English', 45),
	('Edward', 'History', 78);

USE
	University;

--сделаем выборку из нашей исходной таблицы

SELECT
	*
FROM
	dbo.Class;

--перевернем данные из строк в столбцы используя PIVOT

SELECT
	*
FROM
	(SELECT 
		StudentName,
		Course,
		Score
	FROM 
		dbo.Class
	) AS ClassTable
PIVOT
	(
		SUM(Score)
			FOR Course IN
				([English],[History])
	) AS SchoolPivot;

--перевернутые данные обратно вернем в строки из столбцов используя UNPIVOT

WITH original AS
	(SELECT
		*
	FROM
		(SELECT 
			StudentName,
			Course,
			Score
		FROM 
			dbo.Class
		) AS ClassTable
	PIVOT
		(
			SUM(Score)
				FOR Course IN
					([English],[History])
		) AS SchoolPivot
	UNPIVOT
		(Score
			FOR Course IN
				(English, History)
		) AS SchoolUnpivot)
SELECT
	StudentName,
	Course,
	Score
FROM
	original
ORDER BY
	1 DESC;


--Коррелируемый подзапрос:
SELECT
	P.Name,
	P.ListPrice, 
	(SELECT
		PM.Name 
	 FROM
		Production.ProductModel AS PM
	 WHERE
		PM.ProductModelID = P.ProductID) AS Model 
FROM
	Production.Product AS P;

--Вариант решения через LEFT JOIN

SELECT
	P.Name,
	P.ListPrice,
	PM.Name
FROM
	Production.Product AS P
LEFT JOIN
	Production.ProductModel AS PM
		ON PM.ProductModelID = P.ProductID;

--Пример не коррелируемого запроса:

--Вариант 1

SELECT
	SOH.SalesOrderID,
	SOH.OrderDate,
	SOH.CustomerID
FROM
	Sales.SalesOrderHeader AS SOH
WHERE
	SOH.CustomerID = (SELECT
				C.CustomerID
			  FROM
				Sales.Customer AS C
			  JOIN
				Person.Person AS P
					ON C.PersonID = P.BusinessEntityID
			  WHERE
				P.LastName = 'Sullivan'
				AND
				P.FirstName = 'Michael');

--Вариант 2

SELECT
	SP.BusinessEntityID 
FROM
	Sales.SalesPerson AS SP 
WHERE
	SP.Bonus > (SELECT
		    	MIN(SP.Bonus) 
		    FROM
			Sales.SalesPerson AS SP);

--Подзапрос с использованием ALL

SELECT
	BusinessEntityID,
	Bonus
FROM
	Sales.SalesPerson 
WHERE
	Bonus > ALL (SELECT
			Bonus 
		     FROM
			Sales.SalesPerson
		     WHERE
			SalesQuota = 250000);

--Подзапрос с использованием ANY

SELECT
	BusinessEntityID,
	Bonus
FROM
	Sales.SalesPerson 
WHERE
	Bonus > ANY (SELECT
			Bonus 
		     FROM
			Sales.SalesPerson
		     WHERE
			SalesQuota = 250000);

--подзапрос с использованием IN

SELECT
	SalesOrderID,
	OrderDate,
	AccountNumber,
	CustomerID,
	SalesPersonID,
	TotalDue
FROM
	Sales.SalesOrderHeader
WHERE
	SalesPersonID
		IN
			(279, 286, 289);

--подзапрос с использованием NOT IN

SELECT
	SalesOrderID,
    	OrderDate,
    	AccountNumber,
    	CustomerID,
    	SalesPersonID,
    	TotalDue
FROM
	Sales.SalesOrderHeader
WHERE
	SalesPersonID
		NOT IN
			(SELECT
				BusinessEntityID
             		 FROM
				Sales.SalesPerson
             		 WHERE
				Bonus > 5000);

--с помощью подзапроса проверить существуют ли у нас не заполненные идентификаторы заказа с помощью подзапроса с использованием IN

SELECT
	SalesOrderID,
	RevisionNumber,
	OrderDate
FROM
	Sales.SalesOrderHeader
WHERE
	SalesOrderID
		IN (SELECT NULL);

--подзапрос с использованием EXISTS

SELECT
	SOH.SalesOrderID,
	SOH.OrderDate
FROM
	Sales.SalesOrderHeader AS SOH
WHERE
	EXISTS (SELECT
			*
            	FROM
			Sales.SalesPerson AS SP
            	WHERE
			SP.SalesYTD > 3000000
			AND
			SOH.SalesPersonID = SP.BusinessEntityID);

--подзапрос с использованием NOT EXISTS

SELECT
	SOH.SalesOrderID,
	SOH.OrderDate
FROM
	Sales.SalesOrderHeader AS SOH
WHERE
	NOT EXISTS (SELECT
			*
            	FROM
			Sales.SalesPerson AS SP
            	WHERE
			SP.SalesYTD > 3000000
			AND
			SOH.SalesPersonID = SP.BusinessEntityID);

--Пример рекурсивного CTE

WITH cte_numbers (number_day, weekday) AS
(
	SELECT 
		0, 
        DATENAME(DW, 0)
    UNION ALL
    SELECT    
        number_day + 1, 
        DATENAME(DW, number_day + 1)
    FROM    
        cte_numbers
    WHERE
		number_day < 6
)
SELECT 
	number_day,
    weekday
FROM 
    cte_numbers;

--Вариант 1 написания конструкции CASE

SELECT
	ContactTypeID,
	CASE ContactTypeID
		WHEN 2 THEN 'Two'
		WHEN 1 THEN 'One'
		WHEN 0 THEN 'Zero'
		ELSE 'Other'
	END AS number
FROM
	Person.ContactType
WHERE
	ContactTypeID < 10;

--Вариант 2 написания конструкции CASE

SELECT
	ContactTypeID,
    	CASE
		WHEN ContactTypeID = 2 THEN 'Two'
		WHEN ContactTypeID = 1 THEN 'One'
		WHEN ContactTypeID = 0 THEN 'Zero'
		ELSE 'Other'
	END AS number
FROM
	Person.ContactType
WHERE
	ContactTypeID < 10;

--Пример объясления переменных в конструкции CASE:

--Пример 1

DECLARE
	@a TINYINT = 1,
	@b VARCHAR(10) = 'Привет!',
	@c BIT

SELECT
	CASE
		WHEN @a > 2 THEN N'a больше 2. Это неверно.'
		WHEN LEN(@b) = 10 THEN N'b состоит из 10 символов. Это неверно.'
		WHEN @c IS NULL AND @b LIKE 'П%' THEN N'c содержит пустое значение! b начинается с буквы «П»! Это верно!'
		ELSE N'Очевидно, мы не знаем, что происходит'
	END AS выражение;

--Пример 2 (меняем значение переменной а)

DECLARE
	@a TINYINT = 3,
	@b VARCHAR(10) = 'Привет!',
	@c BIT

SELECT
	CASE
		WHEN @a > 2 THEN N'a больше 2.'
		WHEN LEN(@b) = 10 THEN N'b состоит из 10 символов.'
		WHEN @c IS NULL AND @b LIKE 'П%' THEN N'c содержит пустое значение! b начинается с буквы «П»!'
		ELSE N'Очевидно, мы не знаем, что происходит'
	END AS выражение;


--Пример 3 (меняем значение переменной b)

DECLARE
	@a TINYINT = 1,
	@b VARCHAR(10) = 'Объявление',
	@c BIT

SELECT
	CASE
		WHEN @a > 2 THEN N'a больше 2.'
		WHEN LEN(@b) = 10 THEN N'b состоит из 10 символов.'
		WHEN @c IS NULL AND @b LIKE 'П%' THEN N'c содержит пустое значение! b начинается с буквы «П»!'
		ELSE N'Очевидно, мы не знаем, что происходит'
	END AS выражение;

--Пример 4 (меняем значение переменной b, чтобы выполнялось последнее условие)

DECLARE
	@a TINYINT = 1,
	@b VARCHAR(10) = 'Новости',
	@c BIT = 0

SELECT
	CASE
		WHEN @a > 2 THEN N'a больше 2.'
		WHEN LEN(@b) = 10 THEN N'b состоит из 10 символов.'
		WHEN @c IS NULL AND @b LIKE 'П%' THEN N'c содержит пустое значение! b начинается с буквы «П»!'
		ELSE N'Очевидно, мы не знаем, что происходит'
	END AS выражение;






















