Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Как написать функцию, которая формирует новые цены для товаров?  [new]
ally-a
Member

Откуда: Санкт-Петербург
Сообщений: 10
Здравствуйте.
Мне нужно написать функцию, которая увеличивает стоимость товара на 5% от его предыдущей стоимости при каждой следующей покупке.
То есть если его купили первый раз, то цена остается начальной (столбец Стоимость в таблице Товар); если его купили второй раз, то цена увеличивается на 5% от начальной; если в третий - цена увеличивается на 5% от второй и так далее.
Во вложениях скрипт базы и тестовые данные.

К сообщению приложен файл (test_script.sql - 1Kb) cкачать
27 окт 19, 19:03    [22003718]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
Почему именно функция? По идее будет триггер, срабатывающий на вставку в таблицу [Содержимое_чека], и меняющий значение поля [Товар].[Стоимость]. Примерно так:
CREATE TRIGGER [Содержимое_чека_Вставка]
    ON [Содержимое_чека]
    AFTER INSERT
AS
BEGIN
    UPDATE [Товар]
    SET [Товар].[Стоимость] = [Товар].[Стоимость] * 1.05
    WHERE [Товар].[Код_товара] = inserted.[Код_товара]
END

При этом у вас в таблице [Содержимое_чека] есть большой-большой косяк: нет цен. То есть не будет возможности посмотреть, по какой цене был продан товар. У вас есть только текущая цена и только содержание чека. И дат нет.

Ещё я бы сделал поля [Товар].[Название], [Товар].[Стоимость], [Содержимое_чека].[Количество] NOT NULL. Ну и добавил поля: [Содержимое_чека].[Стоимость_продажи], [Содержимое_чека].[Стоимость_по_ценнику], поля с датами, и всё это строго NOT NULL.
27 окт 19, 19:58    [22003730]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
ally-a
Member

Откуда: Санкт-Петербург
Сообщений: 10
Андрей Юниор,
База по заданию такая и должна быть, в этом сложность.
27 окт 19, 20:03    [22003732]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
То есть должна быть строго функция... Хорошо. Тогда напишите пример, как должно выглядеть правильное использование функции. Я задание не понял.
27 окт 19, 20:18    [22003737]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
ally-a
Member

Откуда: Санкт-Петербург
Сообщений: 10
Андрей Юниор,
Вот такая задумка была сначала, но тут увеличивает 5% только от начальной цены.

Create function f3()
returns @t table (Номер_чека int, Стоимость int)
as
begin
Insert @t 

	SELECT Чек.Номер_чека, SUM((Товар.Стоимость * dbo.Содержимое_чека.Количество)+(Товар.Стоимость * dbo.Содержимое_чека.Количество)/100*5) AS Стоимость_чека
	FROM dbo.Содержимое_чека
	INNER JOIN dbo.Товар ON dbo.Содержимое_чека.Номер_чека  = dbo.Товар.Код_товара
	INNER JOIN dbo.Чек ON dbo.Чек.Номер_чека = dbo.Содержимое_чека.Номер_чека 
	WHERE dbo.Содержимое_чека.Номер_чека  in
	(
		SELECT Чек.Номер_чека
		FROM Чек
	)
	group by Чек.Номер_чека

return
end
go

Select * from dbo.f3()
27 окт 19, 20:24    [22003739]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
Меня интересует в первую очередь ИСПОЛЬЗОВАНИЕ функции.
27 окт 19, 20:36    [22003744]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
ally-a
returns @t table (Номер_чека int, Стоимость int)

Понял. Нужно чеки пронумеровать с помощью https://docs.microsoft.com/ru-RU/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-2017 (ранжирующие функции, наверное).

А потом умножить исходную цену на (1.05)^{номер по порядку возрастания}.
27 окт 19, 20:44    [22003745]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
fkthat
Member

Откуда:
Сообщений: 2965
У тебя БД гамно плохая. При каждом изменении цены товара она будет меняться во всех чеках, даже в которых она была на момент создания чека совсем другой. И еще, осилил бы ты юникод, коль уж кириллицу используешь, 2020 год уже на подходе как-никак :)
28 окт 19, 00:10    [22003806]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
fkthat
У тебя БД гамно плохая

Это задание. Скорее всего в ВУЗ'е. Я даже написал небольшую тираду на тему бессмысленности и вредности подобных учебных примеров, но решил воздержаться - божий день всё-таки.
28 окт 19, 00:15    [22003807]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
PsyMisha
Member

Откуда: другая столица
Сообщений: 769
Андрей Юниор
Это задание. Скорее всего в ВУЗ'е.


Ну слав Богу! А то я уже хотел начать спрашивать, что за наименование магазина такого волшебного, чтоб никогда туда не заходить)
28 окт 19, 09:20    [22003865]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Glebanski
Member

Откуда: Msk ->NL
Сообщений: 308
Ну так и напишите функцию CalcnewPrice, обычную скалярную с одним параметром : цена предыдущей продажи и цвторым параметром - цена товара из справочника . В ней умножьте цену на 1.05 :D если первый параметр
Not Null или верните просто второй параметр.

Ну а во внешнем запросе через LAG считайте значение цены из предыдущей продажи (вернёт Null если таковой не было). Это и будет ваш первый параметр для функции.
Саму функцию зовёте в том же селекте
31 окт 19, 13:09    [22007077]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Glebanski
Member

Откуда: Msk ->NL
Сообщений: 308
PS: если преподаватель попросит делать селекты в функции, можете смерить его скептическим взглядом а-ля Шелдон Купер
31 окт 19, 13:13    [22007085]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
ally-a
Member

Откуда: Санкт-Петербург
Сообщений: 10
А через цикл WHILE это можно как-то сделать?
17 ноя 19, 20:32    [22018307]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
ally-a
А через цикл WHILE это можно как-то сделать?

Зачем цикл? Что у вас не получается?
17 ноя 19, 22:54    [22018333]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
ally-a
Member

Откуда: Санкт-Петербург
Сообщений: 10
Если честно, ничего не получается.
А цикл - первое, что в голову приходит.
17 ноя 19, 23:24    [22018341]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
Первое, что должно приходить в голову, чёткая постановка задачи. А у вас задача в разных сообщениях формулируется противоречиво. В первом сообщении требуется изменять данные в таблицах:
ally-a
Мне нужно написать функцию, которая увеличивает стоимость товара на 5% от его предыдущей стоимости при каждой следующей покупке.
То есть если его купили первый раз, то цена остается начальной (столбец Стоимость в таблице Товар); если его купили второй раз, то цена увеличивается на 5% от начальной; если в третий - цена увеличивается на 5% от второй и так далее.
Во вложениях скрипт базы и тестовые данные.

Во другом сообщении, где вы объявляете функции, вы просто возвращаете номер чека и стоимость. При этом на входе в функцию у вас не задач параметр - я предположу, что тут должен быть товар, и функция должна вернуть таблицу по конкретному товару (иначе каша):
ally-a
Create function f3()
returns @t table (Номер_чека int, Стоимость int)

Так что вам в итоге требуется: изменить стоимость товара в [dbo].[Товар] или просто вернуть цену товара в чеках? Как в дословно сформулировано задание?
17 ноя 19, 23:41    [22018350]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
ally-a
Member

Откуда: Санкт-Петербург
Сообщений: 10
Дословно: Создать функцию, формирующую новые стоимости для товаров: каждая новая покупка увеличивает стоимость на 5%.
Оригинальную таблицу [dbo].[Товар] менять не нужно. Только функция, которая возвращает новые посчитанные цены.
17 ноя 19, 23:56    [22018358]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
CREATE FUNCTION f3()
    RETURNS @t TABLE
               (
                   [Код_товара] INT NOT NULL,
                   [Стоимость]  INT NOT NULL
               )
AS
BEGIN
    INSERT INTO @t (Код_товара, Стоимость)
    SELECT Т.Код_товара,
           power(min(Т.Стоимость), count(DISTINCT Ч.Номер_чека)) AS [Стоимость]
    FROM dbo.Содержимое_чека AS Сч
             INNER JOIN dbo.Товар AS Т ON Сч.Номер_чека = Т.Код_товара
             INNER JOIN dbo.Чек AS Ч ON Ч.Номер_чека = Сч.Номер_чека
    GROUP BY Т.Код_товара


    RETURN
END
GO

SELECT *
FROM f3()

Проверить не могу, так как у вас ошибки в заполнении таблиц.
18 ноя 19, 00:39    [22018374]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
ally-a
Member

Откуда: Санкт-Петербург
Сообщений: 10
Эта функция просто выводит цены товаров, а мне нужно, чтобы она вывела НОВЫЕ цены, которые меняются вместе с количеством заказов этих товаров.
В оригинальной таблице мнет не нужно их менять, мне нужно чтобы функция показала новые цены.
18 ноя 19, 00:45    [22018377]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Gerros
Member

Откуда: Харьков
Сообщений: 501
select
  p.[Код_товара]
, p.[Стоимость] * exp( log( 1.05) * count( distinct r.[Номер_чека]))
, p.[Стоимость] * exp( log( 1.05) * sum( r.[Количество]))
from [Содержимое_чека] r
join [Товар] p on p.[Код_товара] = r.[Код_товара]
group by p.[Код_товара], p.[Стоимость]


Сообщение было отредактировано: 18 ноя 19, 04:40
18 ноя 19, 04:39    [22018391]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
PizzaPizza
Member

Откуда:
Сообщений: 365
ally-a
Эта функция просто выводит цены товаров, а мне нужно, чтобы она вывела НОВЫЕ цены, которые меняются вместе с количеством заказов этих товаров.
В оригинальной таблице мнет не нужно их менять, мне нужно чтобы функция показала новые цены.



У вас цены меняются вместе с количеством заказов. Значит в выводе должна быть история цены на товар?
1 - 100
2 - 105
3 - 110.25
4 - ...

Возможно должен быть порядок какой то, который вы не сообщаете нам.

ally-a
НОВЫЕ цены, которые меняются


Звучит крайне абстрактно. Сами что ли меняются прям на экране мигают и скачут по всем строчкам?
Покажите как должен выглядеть результат по вашему мнению.
18 ноя 19, 06:19    [22018399]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
PizzaPizza
Member

Откуда:
Сообщений: 365
ally-a
А цикл - первое, что в голову приходит.


А вы точно базы данных изучаете, теорию множеств и все такое? Вроде первому, чему учат, это думать множествами, а не переборами значений. БД это не регулярное программирование, а если будете применять подходы из, скажем так, не-декларативного программирования, то будете страдать и писать неэффективный код.
18 ноя 19, 06:27    [22018400]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
ally-a
Эта функция просто выводит цены товаров, а мне нужно, чтобы она вывела НОВЫЕ цены, которые меняются вместе с количеством заказов этих товаров.

Функция выводит последнюю цену с учётом количества чеков с данным товаром - формально это и есть НОВЫЕ цены - после внесения очередного чека стоимость товара пересчитывается. Если нужна БУДУЩАЯ цена, то нужно показатель степени увеличить на 1:
power(min(Т.Стоимость), count(DISTINCT Ч.Номер_чека) + 1) AS [Стоимость]
18 ноя 19, 10:44    [22018492]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
ally-a
Member

Откуда: Санкт-Петербург
Сообщений: 10
Вы можете переделать этот код, чтобы он считал ДЛЯ КАЖДОГО ТОВАРА, КОТОРЫЙ ЕСТЬ В ТАБЛИЦЕ [Содержимое_чека], а не для вводимого мной?
И чтобы выводилась не только получившаяся цена, но и код_товара.
То есть, таблица, в которой [Код_товара] и [Цена]

DROP FUNCTION f6
GO

Create function f6(@x int)
returns int
as
begin
declare @id int, @stuff INT, @price INT, @i int
	set @i = 0
	select @id=(SELECT top(1) Код_товара FROM Содержимое_чека WHERE Код_товара = @x), 
	@stuff=(SELECT top(1) COUNT(Код_товара) FROM Содержимое_чека WHERE Код_товара = @x), 
	@price=(SELECT top(1) Товар.Стоимость FROM Содержимое_чека INNER JOIN Товар on Товар.Код_товара = Содержимое_чека.Код_товара WHERE Товар.Код_товара = @x)
	while @i < @stuff
	begin
		set @price = @price + @price*0.03
		set @i = @i+1
	end
	return @price
END
GO

SELECT [dbo].[f6](2)
GO
18 ноя 19, 11:17    [22018516]     Ответить | Цитировать Сообщить модератору
 Re: Как написать функцию, которая формирует новые цены для товаров?  [new]
Андрей Юниор
Member

Откуда: Москва
Сообщений: 510
Объясните, чем вас не устраивают предложенные варианты. Вы их выполняли? Проверяли правильность? Если проверяли, то именно считается неправильно? Предоставьте исходные данные и правильный ответ.

Советую порешать задачи на sql-ex.ru, чтобы понять, что такое sql.
18 ноя 19, 11:44    [22018545]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить