Скачиваний:
7
Добавлен:
17.06.2021
Размер:
16.36 Кб
Скачать
USE Склад_326
GO


/*1 Создайте хранимую процедуру pr_КолебанияСпросаТоваров, которая решает
рассмотренную выше (см. раздел I) задачу определения наименования товара,
по которому был наибольший или наименьший спрос за последние N дней. Эта
процедура должна иметь два входных параметра (@Интервал, @ТипРезультата) и
два выходных параметра (@Имя, @Итог). Если значение входного параметра @ТипРезультата равно 1,
находится товар наибольшего спроса. Если же значение параметра равно 2 – находится товар наименьшего спроса.*/

CREATE PROCEDURE pr_КолебанияСпросаТоваров
@Интервал INT ,
@ТипРезультата INT,
@Имя char(20) OUTPUT,
@Итог INT OUTPUT
AS
DECLARE @Max INT, @Min INT
IF @ТипРезультата = 1
BEGIN
SELECT @Итог = КодТовара, @Max = SUM(Количество)
FROM Заказ
WHERE ДатаЗаказа BETWEEN GetDate() - @Интервал AND GetDate()
GROUP BY КодТовара
ORDER BY SUM(Количество)
SELECT @Имя = Наименование
FROM Товар
WHERE КодТовара = @Итог
END
ELSE
BEGIN
SELECT @Итог = КодТовара, @Min = SUM(Количество)
FROM Заказ
WHERE ДатаЗаказа BETWEEN GetDate() - @Интервал AND GetDate()
GROUP BY КодТовара
ORDER BY SUM(Количество) DESC
SELECT @Имя = Наименование
FROM Товар
WHERE КодТовара = @Итог
END
GO



DECLARE @Интервал1 INT, @ТипРезультата1 INT, @Имя1 char(20) , @Итог1 INT
SELECT @Интервал1 = 1000, @ТипРезультата1 = 1
EXEC pr_КолебанияСпросаТоваров @Интервал1, @ТипРезультата1 , @Имя1 OUTPUT, @Итог1 OUTPUT
SELECT @Имя1 AS [Наименование], @Итог1 AS [Код Товара]
GO

DROP PROCEDURE pr_КолебанияСпросаТоваров -- удаляем проецедуру
GO

/*2
Создайте хранимую процедуру pr_КлиентПоставщик_СтранаИнтервал,
которая подсчитывает, сколько различных клиентов и различных поставщиков
из указанной страны фигурирует в таблице Заказ, причем анализируются только те заказы,
в которых значение поля Дата заказа попадает в указанный интервал дат. Эта процедура
должна иметь три входных параметра (@Страна, @НачалоИнтервала, @КонецИнтервала) и два
выходных параметра (@ЧислоКлиентов, @ЧислоПоставщиков). Если же значение параметра
@Страна не будет указано (т.е. будет равно NULL), то подсчет клиентов и поставщиков
должен вестись независимо от их национальной принадлежности.*/

CREATE PROCEDURE pr_КлиентПоставщик_СтранаИнтервал
@Страна CHAR(20),
@НачалоИнтервала DATETIME,
@КонецИнтервала DATETIME,
@ЧислоКлиентов INT OUTPUT,
@ЧислоПоставщиков INT OUTPUT
AS
IF @Страна IS NOT NULL
BEGIN
CREATE TABLE #goods (
Страна CHAR(20),
ДатаЗаказа DATETIME,
СрокПоставки DATETIME,
Код INT,
КодРегиона INT
)
INSERT #goods
SELECT Регион.Страна, Заказ.ДатаЗаказа, Заказ.СрокПоставки, Заказ.КодПоставщика, Поставщик.КодРегиона
FROM Заказ
INNER JOIN Поставщик ON Заказ.КодПоставщика= Поставщик.КодПоставщика
INNER JOIN Регион ON Поставщик.КодРегиона = Регион.КодРегиона
WHERE Регион.Страна = @Страна AND ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала
ORDER BY Поставщик.КодПоставщика
SELECT @ЧислоПоставщиков = COUNT(DISTINCT Код)
FROM #goods
DELETE FROM #goods
INSERT #goods
SELECT Регион.Страна, Заказ.ДатаЗаказа, Заказ.СрокПоставки, Заказ.КодКлиента
FROM Заказ
INNER JOIN Клиент ON Заказ.КодКлиента = Клиент.КодКлиента
INNER JOIN Регион ON Клиент.КодРегиона = Регион.КодРегиона
WHERE Регион.Страна = @Страна AND ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала
SELECT @ЧислоКлиентов = COUNT(DISTINCT Код)
FROM #goods
END
ELSE
BEGIN
CREATE TABLE #goods2 (
ДатаЗаказа DATETIME,
СрокПоставки DATETIME,
Код INT,
КодРегиона INT
)
INSERT #goods2
SELECT Заказ.ДатаЗаказа, Заказ.СрокПоставки, Заказ.КодПоставщика, Поставщик.КодРегиона
FROM Заказ
INNER JOIN Поставщик ON Заказ.КодПоставщика= Поставщик.КодПоставщика
INNER JOIN Регион ON Поставщик.КодРегиона = Регион.КодРегиона
WHERE ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала
ORDER BY Поставщик.КодПоставщика
SELECT @ЧислоПоставщиков = COUNT(DISTINCT Код)
FROM #goods2
DELETE FROM #goods2
INSERT #goods2
SELECT Заказ.ДатаЗаказа, Заказ.СрокПоставки, Заказ.КодКлиента, Клиент.КодКлиента
FROM Заказ
INNER JOIN Клиент ON Заказ.КодКлиента= Клиент.КодКлиента
INNER JOIN Регион ON Клиент.КодРегиона = Регион.КодРегиона
WHERE ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала
SELECT @ЧислоКлиентов = COUNT(DISTINCT Код)
FROM #goods2
END

GO

SET DATEFORMAT dmy
DECLARE @Страна1 CHAR(20), @НачалоИнтервала1 DATETIME, @КонецИнтервала1 DATETIME, @ЧислоКлиентов1 INT , @ЧислоПоставщиков1 INT
SELECT @Страна1 = 'Беларусь', @НачалоИнтервала1 = '01.01.2010', @КонецИнтервала1 = '01.06.2021'
EXEC pr_КлиентПоставщик_СтранаИнтервал @Страна1, @НачалоИнтервала1, @КонецИнтервала1, @ЧислоКлиентов1 OUTPUT , @ЧислоПоставщиков1 OUTPUT
SELECT @ЧислоКлиентов1 AS [Количество клиентов], @ЧислоПоставщиков1 AS [Количество Поставщиков]
GO

DROP PROCEDURE pr_КлиентПоставщик_СтранаИнтервал
GO

/*3 Создайте хранимую процедуру pr_Товар_СтранаВалютаИнтервал,
которая подсчитывает, сколько различных товаров в конкретной
валюте было заказано клиентами из указанной страны, причем анализируются только те заказы,
в которых значение поля Дата заказа попадает в заданный интервал дат. Эта процедура должна
иметь четыре входных параметра (@Страна, @Валюта, @НачалоИнтервала, @КонецИнтервала) и один
выходной параметр (@ЧислоТоваров). При этом расширьте возможности процедуры следующим образом:
если значение параметра @Страна не будет указано (т.е. будет равно NULL), то подсчет товаров
должен вестись независимо от национальной принадлежности клиента;
если значение параметра @Валюта не будет указано (т.е. будет равно NULL), то подсчет товаров
должен вестись применительно к национальной валюте (код валюты – BYR).*/

CREATE PROCEDURE pr_Товар_СтранаВалютаИнтервал
@Страна VARCHAR(30),
@Валюта VARCHAR(30) = 'BYR',
@НачалоИнтервала DATETIME,
@КонецИнтервала DATETIME
AS
DECLARE @ЧислоТоваров INT
SET @ЧислоТоваров = 0
IF @Валюта IS NULL
BEGIN
SELECT Заказ.КодТовара, Заказ.Количество
INTO #Товары1
FROM Заказ
INNER JOIN Клиент
ON Заказ.КодКлиента = Клиент.КодКлиента
WHERE (Заказ.ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала)
SELECT @ЧислоТоваров = COUNT(DISTINCT Количество)
FROM #Товары1
INNER JOIN Товар ON #Товары1.КодТовара = Товар.КодТовара
WHERE Товар.КодВалюты = @Валюта
END

ELSE
BEGIN
SELECT Заказ.КодТовара, Заказ.Количество
INTO #Товары2
FROM Заказ
INNER JOIN Клиент
ON Заказ.КодКлиента = Клиент.КодКлиента
INNER JOIN Регион
ON Клиент.КодРегиона = Регион.КодРегиона
WHERE (Заказ.ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала) AND Регион.Страна = @Страна

SELECT @ЧислоТоваров = COUNT(DISTINCT Количество)
FROM #Товары2
INNER JOIN Товар ON #Товары2.КодТовара = Товар.КодТовара
WHERE Товар.КодВалюты = @Валюта
END

SELECT @ЧислоТоваров [Количество различных товаров]
GO


EXEC pr_Товар_СтранаВалютаИнтервал 'Беларусь', BYR, "02.01.2006", "02.09.2021"
GO

DROP PROCEDURE pr_Товар_СтранаВалютаИнтервал
GO

/*4Создайте пользовательскую функцию fn_getЧислоДней_вМесяце типа Scalar(скалярное значение
любого из типов данных), которая для
конкретной даты возвращает число дней в месяце, который определяется этой датой
(високосность года не учитывается). Эта функция должна иметь один входной параметр (@Дата).*/

CREATE FUNCTION fn_getЧислоДней_вМесяце
(@Дата DATETIME)
RETURNS INT
BEGIN
DECLARE @Days INT
SET @DAYS = DATEDIFF(DAY, @Дата, DATEADD(MONTH,1,@Дата))
RETURN @Days
END
GO

SET DATEFORMAT dmy
DECLARE @Дата1 DATETIME
SELECT @Дата1 = '16.05.2021'
SELECT dbo.fn_getЧислоДней_вМесяце(@Дата1) AS [Количество дней]
GO

DROP FUNCTION fn_getЧислоДней_вМесяце
GO

/*5. Создайте пользовательскую функцию fn_getФИО_вФормате типа Scalar, которая на основе
текстовой строки, содержащей фамилию, имя и отчество, формирует текстовую строку в одном
из следующих форматов:
1) исходная строка переводится в верхний регистр;
2) исходная строка переводится в нижний регистр;
3) на верхнем регистре должны быть только первые буквы слов;
4) выводится только фамилия, а имя и отчество заменяются их первыми буквами с точкой.
Эта функция должна иметь два входных параметра (@ФИО, @Формат).
Усложненный вариант. Расширьте возможности функции таким образом, чтобы была
допустима исходная строка (задаваемая параметром @ФИО), содержащая не один, а несколько
пробелов между фамилией и именем или между именем и отчеством, а также допускающая наличие
лидирующих пробелов перед фамилией.*/



CREATE FUNCTION fn_getФИО_вФормате
(@ФИО char(30), @Формат int)
RETURNS CHAR(30)
BEGIN
DECLARE @RESULT char(30)
DECLARE @surname char(10)
DECLARE @name char(10)
DECLARE @patronymic char(10)
IF @Формат = 1
BEGIN
SELECT @RESULT = UPPER(@ФИО)
END
IF @Формат = 2
BEGIN
SELECT @RESULT = LOWER(@ФИО)
END
IF @Формат = 3
BEGIN /*CHARINDEX(substring, string, start)
SUBSTRING(string, start, length)*/
DECLARE @pos INT
SELECT @pos = CHARINDEX(' ', @ФИО)
SELECT @surname = SUBSTRING(@ФИО, 1, @pos-1)
SELECT @ФИО = SUBSTRING(@ФИО, @pos+1, LEN(@ФИО)-@pos)
SELECT @pos = CHARINDEX(' ', @ФИО)
SELECT @name = SUBSTRING(@ФИО, 1, @pos-1)
SELECT @ФИО = SUBSTRING(@ФИО, @pos+1, LEN(@ФИО)-@pos)
SELECT @patronymic = @ФИО
SELECT @RESULT = UPPER(LEFT(@surname,1))+LOWER(SUBSTRING(@surname,2,LEN(@surname)))+' '+
UPPER(LEFT(@name,1))+LOWER(SUBSTRING(@name,2,LEN(@name)))+' '+
UPPER(LEFT(@patronymic,1))+LOWER(SUBSTRING(@patronymic,2,LEN(@patronymic)))
RETURN @RESULT
/*
SELECT @surname = SUBSTRING (@ФИО, 1, CHARINDEX(' ', @ФИО))
SELECT @surname = LOWER(@surname)
SELECT @surname = UPPER(LEFT(@surname,1))+SUBSTRING(@surname,2,LEN(@surname)-1)
SELECT @name = SUBSTRING (@ФИО, CHARINDEX(' ', @ФИО)+1, CHARINDEX(' ', @ФИО,CHARINDEX(' ',LEN(@ФИО))))
SELECT @name = LOWER(@name)
SELECT @name = UPPER(LEFT(@name,1))+SUBSTRING(@name,2,LEN(@name))
SELECT @patronymic = SUBSTRING (@ФИО, CHARINDEX(' ', @ФИО,CHARINDEX(' ', @ФИО)+1)+1,LEN(@ФИО))
SELECT @patronymic = LOWER(@patronymic)
SELECT @patronymic = UPPER(LEFT(@patronymic,1))+SUBSTRING(@patronymic,2,LEN(@patronymic))
SELECT @RESULT = @surname + @name + @patronymic*/
END
IF @Формат = 4
BEGIN
SELECT @surname = SUBSTRING (@ФИО, 1, CHARINDEX(' ', @ФИО))
SELECT @surname = LOWER(@surname)
SELECT @surname = UPPER(LEFT(@surname,1))+SUBSTRING(@surname,2,LEN(@surname))
SELECT @name = SUBSTRING (@ФИО, CHARINDEX(' ', @ФИО)+1, CHARINDEX(' ', @ФИО,CHARINDEX(' ',LEN(@ФИО))))
SELECT @name = LOWER(@name)
SELECT @name = UPPER(LEFT(@name,1)) + '.'
SELECT @patronymic = SUBSTRING (@ФИО, CHARINDEX(' ', @ФИО,CHARINDEX(' ', @ФИО)+1)+1,LEN(@ФИО))
SELECT @patronymic = LOWER(@patronymic)
SELECT @patronymic = UPPER(LEFT(@patronymic,1)) + '.'
SELECT @RESULT = @surname + @name + @patronymic
END
RETURN @RESULT
END
GO


DECLARE @ФИО1 char(30)
DECLARE @Формат1 int
SET @ФИО1 ='Хомякова Анна Александро'
SELECT dbo.fn_getФИО_вФормате(@ФИО1,3) AS [Работа со строкой]
GO

DROP FUNCTION fn_getФИО_вФормате
GO




--6Создайте пользовательскую функцию fn_getGroup_НаименованиеВалюта типа Inline Table-valued, которая возвращает
--таблицу со следующими столбцами:

--Наименование товара
--Имя валюты
--Заказанное кол-во
--Стоимость в национальной валюте



--Эта таблица должна отражать результат группировки данных по полям Наименование и ИмяВалюты. Для каждой
-- такой группы подсчитывается итоговое количество заказанного товара и итоговая стоимость в национальной валюте.
--Пользовательская функция fn_getGroup_НаименованиеВалюта должна иметь два входных параметра (@НачалоИнтервала, @КонецИнтервала),
-- поэтому при формировании результирующей таблицы необходимо учитывать только те строки из таблицы Заказ, в которых значение
-- поля Дата заказа попадает в указанный параметрами интервал дат.



CREATE FUNCTION fn_getGroup_НаименованиеВалюта
(@НачалоИнтервала DATE, @КонецИнтервала DATE)
RETURNS TABLE
AS RETURN
SELECT Товар.Наименование as [Наименование товара], Валюта.ИмяВалюты AS [Имя валюты], SUM(Заказ.Количество) AS Количество, (SUM(Заказ.Количество) * Товар.Цена) AS [Стоимость в валюте]
FROM Заказ
INNER JOIN Товар ON Заказ.КодТовара = Товар.КодТовара
INNER JOIN Валюта ON Валюта.КодВалюты = Товар.КодВалюты
WHERE (Заказ.ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала)
GROUP BY Товар.Наименование, Валюта.ИмяВалюты, Товар.Цена
GO

SET DATEFORMAT dmy
SELECT * FROM fn_getGroup_НаименованиеВалюта('01.07.2008','15.07.2021')
GO

DROP FUNCTION fn_getGroup_НаименованиеВалюта
GO


--7Создайте пользовательскую функцию fn_getTable_СтоимостьНВ типа Multi-statement Table-valued,
--которая возвращает таблицу со следующими столбцами:

/*Номер
Дата заказа
Имя клиента
Наименование товара
Количество
Цена в НВ
Стоимость в НВ*/


/*Эта таблица строится в три этапа. Сначала создается таблица со столбцами, показанными выше, где
столбец Номер является автоинкрементным первичным ключом,
столбцы Цена в НВ (цена в национальной валюте)
и Стоимость в НВ (стоимость в национальной валюте) являются вычисляемыми.
Число строк этой таблицы будет равно числу строк в таблице Заказ.

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

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

CREATE FUNCTION fn_getTable_СтоимостьНВ ()
RETURNS @multi TABLE (
Номер INT IDENTITY(1,1) PRIMARY KEY,
ДатаЗаказа DATE NOT NULL,
ИмяКлиента VARCHAR(30) NOT NULL,
НаименованиеТовара VARCHAR(20) NOT NULL,
Количество INT NOT NULL,
ЦенаВНацВалюте INT NOT NULL,
СтоимостьВНацВалюте INT NOT NULL)
BEGIN

DECLARE @rowset TABLE (
Номер INT IDENTITY(1,1) PRIMARY KEY,
ДатаЗаказа date NOT NULL,
ИмяКлиента varchar(30) NOT NULL,
НаименованиеТовара VARCHAR(20) NOT NULL,
Количество INT NOT NULL,
ЦенаВНацВалюте INT NULL,
СтоимостьВНацВалюте INT NULL)
INSERT @rowset (ДатаЗаказа, ИмяКлиента, НаименованиеТовара, Количество, ЦенаВНацВалюте, СтоимостьВНацВалюте)
SELECT ДатаЗаказа, ИмяКлиента, Наименование, Количество, Цена, (Цена*Количество)
FROM Заказ
INNER JOIN Клиент ON Заказ.КодКлиента=Клиент.КодКлиента
INNER JOIN Товар ON Заказ.КодТовара = Товар.КодТовара
DECLARE @Price INT
SELECT @Price=AVG(СтоимостьВНацВалюте)

FROM @rowset
DELETE
FROM @rowset
WHERE СтоимостьВНацВалюте < @Price
INSERT @multi
SELECT ДатаЗаказа, ИмяКлиента, НаименованиеТовара, Количество, ЦенаВНацВалюте, СтоимостьВНацВалюте
FROM @rowset
RETURN
END
GO

SELECT * FROM fn_getTable_СтоимостьНВ()
GO

DROP FUNCTION fn_getTable_СтоимостьНВ




/*
DECLARE @Counter INT
SELECT @Counter = count(*)
FROM @rowset
SELECT @Price = (SUM(СтоимостьВНацВалюте)/@Counter)*/



CREATE PROCEDURE pr_СоздатьТаблицу
@Имя CHAR(20) ,
@Фамилия CHAR(20),
@Возраст INT
AS
--DECLARE @Имя CHAR(20), @Фамилия CHAR(20),@Возраст INT
CREATE TABLE #ABC (
A CHAR(20),
B CHAR(20),
C INT
)
INSERT INTO #ABC
VALUES(@Имя, @Фамилия,@Возраст)
SELECT @Имя AS [A], @Фамилия AS [B], @Возраст AS [C]

GO

DECLARE @Имя1 CHAR(20), @Фамилия1 CHAR(20), @Возраст1 INT
SELECT @Имя1 = 'Анна', @Фамилия1 = 'Хомякова', @Возраст1 = 18
EXEC pr_СоздатьТаблицу @Имя1, @Фамилия1, @Возраст1
GO

DROP PROCEDURE pr_СоздатьТаблицу
GO
Соседние файлы в папке чужие лабы бд и прочее