Повторный вызов функции и объединение ее выходных данных

#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;