#sql-server
#sql-server
Вопрос:
У меня есть 1 функция, предоставленная мне, которая принимает параметры @month и @year. Функция возвращает таблицу, подобную этой: предполагая, что @месяц = 9 и @год = 2020
select * FROM dbo.TotalClicksForMonth(9,2020)
Partner,Percentage
Partner1,0.25
Partner2,0.5
Partner3,0.25
У меня есть скалярная функция, которая возвращает значение с плавающей точкой
select dbo.TotalSpendForMonth(9,2020)
100
Если я выполняю оператор select
select dbo.TotalSpendForMonth(9,2020)*cp.PercentageClicks as percentsplit from dbo.TotalClicksForMonth(9,2020) as cp
Это работает, и я получаю вывод, подобный
Partner PercentageClicks percentsplit
Partner1 0.25 25
Partner2 0.50 50
Partner3 0.25 25
Берем общую сумму и распределяем ее по всем строкам в правильных соотношениях.
Теперь это нормально для сентября 2020 года (9,2020). Но мне нужны выходные данные за все месяцы и годы, указанные в 3-й таблице
select datepart(MONTH,[date]) as mh,datepart(year,[date]) as yr
from sales
Я не могу понять, как это сделать.
Я пытался
select datepart(MONTH,sales.date) as mh,datepart(year,sales.date) as yr
join (select dbo.TotalspendForMonth(sales.mh,sales.yr)*cp.PercentageClicks as percentsplit from dbo.TotalClicksForMonth(sales.mh,sales.yr) as cp) as xx on 1=1
from sales
group by datepart(MONTH,sales.date),datepart(year,sales.date)
Но это не работает.
Я думаю, что мои варианты заключаются в создании временной таблицы, а затем многократном вызове курсором оператора select для добавления строк, но должен быть лучший способ,
Не могли бы вы помочь, пожалуйста?
Комментарии:
1. Присоедините уже сгруппированные m y к таблицам кликов и т. Д.
2. Я не могу изменить функции. Я должен использовать их такими, какие они есть. Им нужны месяц и год, передаваемые им, и возвращают несколько строк, список партнеров, на которых должна быть разделена общая сумма. Последний выбор в моем вопросе — это то, что я пробовал, но не выполняется, я думаю, потому что нет условия для включения соединения. Я искусственно использовал 1 = 1 для всех строк, но это не работает.
3. количество раз, когда мне нужно вызывать эти функции, является переменным и зависит от дат в таблице продаж, но обычно 10-20 месяцев.
Ответ №1:
Кажется, что вам нужно сделать, это APPLY
для функции:
SELECT DATEPART(MONTH,s.[date]) AS mh,
DATEPART(year,s.[date]) AS yr,
dbo.TotalSpendForMonth(DATEPART(MONTH,s.[date]),DATEPART(year,s.[date])) * cp.PercentageClicks AS percentsplit
FROM dbo.sales s
CROSS APPLY dbo.TotalClicksForMonth(DATEPART(MONTH,s.[date]),DATEPART(year,s.[date])) cp;
Если вы предпочитаете, вы можете получить DATEPART
s в VALUES
табличной конструкции, чтобы не повторять выражения:
SELECT V.mh,
V.yr,
dbo.TotalSpendForMonth(V.mh,V.yr) * cp.PercentageClicks AS percentsplit
FROM dbo.sales s
CROSS APPLY (VALUES(DATEPART(MONTH,s.[date]),DATEPART(year,s.[date])))V(mh,yr)
CROSS APPLY dbo.TotalClicksForMonth(V.mh,V.yr) cp;
Комментарии:
1. На шаг ближе, но для 9,2020 теперь есть много строк (> 100) вместо 3
2. Я не понимаю, на что ты намекаешь, @JohnnyJP . Если
sales
имеет несколько строк, то он будет вызывать функцию для каждой строки, а не только для одной из них.3. Итак, я хочу вызвать select dbo. TotalSpendForMonth(9,2020)*cp.PercentageClicks как percentsplit из dbo. TotalClicksForMonth(9,2020) как cp
4. Я хочу вызвать его для значений, определенных в sales . итак, (9,2020) (10,2020), (11,2020) и так далее
5. Таким образом, количество строк при самостоятельном вызове (9,2020), выполняющем этот выбор, равно 3, если он вызывает другие диапазоны дат, число в сентябре по-прежнему равно трем.
Ответ №2:
Для вычисления процента кликов вы можете ПЕРЕКРЕСТНО ПРИМЕНИТЬ функцию с табличным значением. Для подведения итогов по МЕСЯЦАМ и ГОДАМ вы можете использовать агрегатную функцию SUM и GROUP BY . Что-то вроде этого.
select dt.mo, dt.yr,
sum(dbo.TotalSpendForMonth(dt.mo, dt.yr)*cp.PercentageClicks) total_amount
from dbo.sales s
cross apply (select datepart(month,s.[date]) as mo,
datepart(year,s.[date]) as yr) dt
cross apply dbo.TotalClicksForMonth(dt.mo, dt.yr) cp
group by dt.mo, dt.yr
order by dt.yr, dt.mo;