Добавил:
rushevamar@mail.ru Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лаба 7 / laba6_7

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


  use СкладЛаба5
  go

  create procedure pr_КолебанияСпросаТоваров
	  @Интервал INT,
	  @ТипРезультата int,
	  @Имя varchar(50) output,
	  @Итог numeric (12,3) output
  as
  declare @Code INT /*создание переменной*/
	if @ТипРезультата = 1
		select @Code=КодТовара, @Итог=sum(Количество) /*присвоение значений нескольким переменным*/
		from Заказ
		where ДатаЗаказа between getdate()-@Интервал and getdate()
		group by КодТовара
		order by sum(Количество)
	else
		select @Code=КодТовара, @Итог=sum(Количество)
		from Заказ
		where ДатаЗаказа between getdate()-@Интервал and getdate()
		group by КодТовара
		order by sum(Количество) desc
	SELECT @Имя = Наименование
	FROM Товар 
	WHERE КодТовара = @Code
  go

  declare @Имя varchar(50), @Итог numeric (12,3)
  exec pr_КолебанияСпросаТоваров 60, 1, @Имя output, @Итог output /*запуск хранимых процедур*/ -- output это выходные параметры
  select @Имя as [Название], @Итог as [Итог]
  go

  declare @Name varchar(50), @Result numeric (12,3)
  exec pr_КолебанияСпросаТоваров 60, 2, @Name output, @Result output
  select @Name as [Название], @Result as [Итог]
  go

 

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

    DROP PROCEDURE pr_КлиентПоставщик_СтранаИнтервал /*удаление хранимой процедуры*/
 GO


create procedure pr_КлиентПоставщик_СтранаИнтервал
	@Страна VARCHAR(20) null   ,
	@НачалоИнтервала DATE,
	@КонецИнтервала DATE,
	@ЧислоКлиентов int output,
	@ЧислоПоставщиков int output
as
	if @Страна is not null
	begin
		select @ЧислоКлиентов = count(DISTINCT(Заказ.КодКлиента)) /*используется для возврата только отдельных (разных) значений*/
		from Заказ inner join Клиент
			on Заказ.КодКлиента=Клиент.КодКлиента
			inner join Регион on Клиент.КодРегиона=Регион.КодРегиона
		where ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала and Страна=@Страна
		select @ЧислоПоставщиков = count(DISTINCT(Заказ.КодПоставщика)) 
		from Заказ inner join Поставщик
			on Заказ.КодПоставщика=Поставщик.КодПоставщика
			inner join Регион on Поставщик.КодРегиона=Регион.КодРегиона
		where ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала and Страна=@Страна
	end
	else 
		select @ЧислоКлиентов = count(DISTINCT(Заказ.КодКлиента)), @ЧислоПоставщиков = count(DISTINCT(Заказ.КодПоставщика)) --DISTINCT используется для указания на то, что следует работать только с уникальными значениями столбца
		from Заказ 
		where ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала 
go

  declare @Client int, @Service int
  declare @Start DATE, @End DATE
  select @Start = '2017-01-01' 
  select @End='2021-04-04' 
  exec pr_КлиентПоставщик_СтранаИнтервал 'Беларусь', @Start, @End, @Client output, @Service output
  select @Client as [Количество клиентов], @Service as [Количество поставщиков]
  go


  declare @Client int, @Service int
  declare @Start datetime, @End datetime
  select @Start='2017-01-01'
  select @End='2021-04-03'
  exec pr_КлиентПоставщик_СтранаИнтервал null, @Start, @End, @Client output, @Service output
  select @Client as [Количество клиентов], @Service as [Количество поставщиков]
  go


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

alter procedure pr_Товар_СтdранаВалютаИнтервал
	@Страна VARCHAR(20) null,
	@Валюта CHAR(3) null,
	@НачалоИнтервала datetime,
	@КонецИнтервала datetime,
	@ЧислоТоваров int output
as
	if @Валюта is null set @Валюта='BYR'
	if @Страна is not null
		select distinct @ЧислоТоваров = count(Заказ.КодТовара)
		from Заказ 
			join Товар on Заказ.КодТовара=Товар.КодТовара
			join Клиент on Заказ.КодКлиента=Клиент.КодКлиента
			join Регион on Клиент.КодРегиона=Регион.КодРегиона
		where КодВалюты=@Валюта and ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала
			and Страна=@Страна
	else
		select distinct @ЧислоТоваров = count(Заказ.КодТовара)
		from Заказ 
			join Товар on Заказ.КодТовара=Товар.КодТовара
			join Клиент on Заказ.КодКлиента=Клиент.КодКлиента
		where КодВалюты=@Валюта and ДатаЗаказа between @НачалоИнтервала and @КонецИнтервала
go


  declare @Country VARCHAR(20), @Currency char(3), @Start datetime, @End datetime, @Res int
  select @Start='2017-01-01', @End='2021-05-05', @Country = 'Россия', @Currency = 'USD'
  exec pr_Товар_СтdранаВалютаИнтервал @Country, @Currency, @Start, @End, @Res output
  select @Res as [Количество товаров]
  go

  declare @Start smalldatetime, @End smalldatetime, @Res int
  select @Start='2017-01-01', @End='2021-13-09'
  exec pr_Товар_СтdранаВалютаИнтервал null, null, @Start, @End, @Res output
  select @Res as [Количество товаров]
  go



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


create function fn_getЧислоДней_вМесяце
	(@Дата date)
returns int
begin
	declare @Res int
	set @Res=day(EOMONTH(@Дата))
	return @Res
end
go

declare @Date date

set @Date ='2016-02-12'
select  @Date AS [ВЫБРАННАЯ ДАТА] , dbo.fn_getЧислоДней_вМесяце(@Date) as [Количество дней]
go

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

create function fn_getФИО_вФормате 
	(@ФИО varchar(50), @Формат int)
returns varchar(50)
begin
	declare @Temp char, @Ind int, @Name varchar(50)
	set @ФИО=ltrim(@ФИО) /*обрезает пробелы, которые стоят в начале строки*/
	set @ФИО=rtrim(@ФИО) /*обрезает пробелы, которые стоят в конце строки*/
	if @Формат=1
		set @ФИО=upper(@ФИО) /* в верхний регистр*/
		else if @Формат=2
			set @ФИО=lower(@ФИО)
				else if @Формат=3
					begin
						set @ФИО = lower(@ФИО)
						set @Temp = left(@ФИО,1)
						set @ФИО = stuff(@ФИО, 1, 1, upper(@Temp))
						set @Ind = charindex(' ', @ФИО)
						set @Temp = substring(@ФИО, @Ind+1, 1)
						set @ФИО = stuff(@ФИО, @Ind+1, 1, upper(@Temp))
						set @Ind = charindex(' ', @ФИО, @Ind+1)
						set @Temp = substring(@ФИО, @Ind+1, 1) -- вырезает и возвращает заданное количество символов из строки
						set @ФИО = stuff(@ФИО, @Ind+1, 1, upper(@Temp))
					end
						else if @Формат=4
							begin
								set @ФИО = lower(@ФИО)
								set @Temp = left(@ФИО,1)
								set @ФИО = stuff(@ФИО, 1, 1, upper(@Temp))
								set @Ind = charindex(' ', @ФИО)
								set @Temp = substring(@ФИО, @Ind+1, 1)
								set @ФИО = stuff(@ФИО, @Ind+1, 1, upper(@Temp))
								set @Name = substring (@ФИО, 1, @Ind+1) + '. '
								set @Ind = charindex(' ', @ФИО, @Ind+1)
								set @Temp = upper(substring(@ФИО, @Ind+1, 1))
								set @Name = @Name + @Temp + '.'
								set @ФИО = @Name
							end
	return @ФИО
end
go


declare @str nvarchar(50)
set @str=' Рушева маргарИТА владисла  '
set @
select dbo.fn_getФИО_вФормате(@str, 4)


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


create function fn_getGroup_НаименованиеВалюта
	(@НачалоИнтервала date, @КонецИнтервала date)
returns table
as return
	SELECT Товар.Наименование AS [Наименование товара], Валюта.ИмяВалюты AS [Имя валюты], COUNT(Заказ.КодЗаказа) AS [Заказанное количество], SUM(Цена) AS [Стоимость в валюте], SUM(Цена*Валюта.КурсВалюты) AS [Стоимость в нац. валюте]
	FROM Заказ 
		INNER JOIN Товар ON Заказ.КодТовара = Товар.КодТовара
		INNER JOIN Валюта ON Товар.КодВалюты = Валюта.КодВалюты
	WHERE (ДатаЗаказа BETWEEN @НачалоИнтервала AND @КонецИнтервала)
	GROUP BY Товар.Наименование, Валюта.ИмяВалюты
GO

SELECT * FROM fn_getGroup_НаименованиеВалюта('2012-01-01', '2026-12-31')
GO



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

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


create function fn_getTable_СтоимостьНВ
()
returns @СтоимостьНВ table(
	Номер INT  IDENTITY(1,1)  PRIMARY KEY,
	ДатаЗаказа DATETIME  DEFAULT getdate()  NULL,
	ИмяКлиента VARCHAR(40)  NOT NULL,
	НаименованиеТовара VARCHAR(50)  NOT NULL,
	Количество NUMERIC(12, 3)  NULL  CHECK (Количество > 0),
	ЦенаНВ MONEY  NULL  CHECK (ЦенаНВ > 0),
	СтоимостьНВ MONEY  NULL  CHECK (СтоимостьНВ > 0)
)
begin
	declare @temp table(
		Номер INT  IDENTITY(1,1)  PRIMARY KEY,
		ДатаЗаказа DATETIME  DEFAULT getdate()  NULL,
		ИмяКлиента VARCHAR(40)  NOT NULL,
		НаименованиеТовара VARCHAR(50)  NOT NULL,
		Количество NUMERIC(12, 3)  NULL  CHECK (Количество > 0),
		ЦенаНВ MONEY  NULL  CHECK (ЦенаНВ > 0),
		СтоимостьНВ MONEY  NULL  CHECK (СтоимостьНВ > 0)
	)
	insert @temp (ДатаЗаказа, ИмяКлиента, НаименованиеТовара, Количество, ЦенаНВ, СтоимостьНВ)
		select ДатаЗаказа, ИмяКлиента, Наименование, Количество, Цена*КурсВалюты, Цена*КурсВалюты*Количество
		from Заказ 
			inner join Клиент on Заказ.КодКлиента=Клиент.КодКлиента
			inner join Товар on Заказ.КодТовара=Товар.КодТовара
			inner join Валюта on Товар.КодВалюты=Валюта.КодВалюты
	
	declare @avg money
	select @avg=avg(СтоимостьНВ)
	from @temp

	delete from @temp
	where СтоимостьНВ<@avg

	insert @СтоимостьНВ 
		select ДатаЗаказа, ИмяКлиента, НаименованиеТовара, Количество, ЦенаНВ, СтоимостьНВ
		from @temp

	return
end
go

select *
from fn_getTable_СтоимостьНВ()




/*Процедура называется блоком PL / SQL, который выполняет одну или несколько задач. 
где функция называется блоком PL / SQL, который выполняет определенное действие. 
Процедура может возвращать или не возвращать значение, 
когда функция as должна возвращать одно значение*/

\



/*создаем процедуру в которой делаем (селект )запрос на выборку выводим
(код зак ,код товара, дата заказа, наимнование товара, цена товара)
для записей у которых дата заказа больше 1ого параметра цена товара процедуры , цена товара в промежутке межлу 2 и 3 параметрмо процедуры
либо наименование начинается с 4 параметра*/


/*создаем процедуру в которой делаем (селект )запрос на выборку выводим КОД ЗАКАЗА, ДАТА ЗАКАЗА, колво заказа, имя клиента  
для записей у которых дата заказа больше 1ого параметра цена товара процедуры , колво в промежутке межлу 2 и 3 параметрмо процедуры
и имя клиента начинается с 4 параметра*/

create PROCEDURE pr_йфыадание
@Парам1 DATETIME,
@Парам2 INT,
@Парам3 INT,
@Парам4 char(20)
AS
SELECT КодЗаказа, ДатаЗаказа, Количество, Товар.Наименование, Товар.Цена
FROM Заказ
INNER JOIN Товар
ON Заказ.КодЗаказа = Товар.КодТовара
WHERE (ДатаЗаказа > @Парам1) OR (Цена BETWEEN @Парам2 AND @Парам3) OR (Товар.Наименование like @Парам4 + '%')
GO

SET DATEFORMAT dmy
DECLARE @Парам1 DATETIME
SET @Парам1 = GETDATE()
EXEC pr_йфыадание @Парам1, 100 , 2000, 'и'
GO

DROP PROCEDURE pr_йфыадание
GO
Соседние файлы в папке лаба 7