Взвешенное среднее в T-SQL (как SUMPRODUCT Excel)

Это - вопрос на Объектно-ориентированном проектировании, не Java язык. Это - вообще хорошая практика, чтобы скрыть типы данных в классе и представить только методы, которые являются частью API класса. Если Вы представляете внутренние типы данных, Вы никогда не можете изменять их в будущем. При сокрытии их единственное обязательство перед пользователем является возвратом метода и типами аргумента.

16
задан ProfK 9 November 2009 в 01:23
поделиться

3 ответа

Ответ Квассноя показывает, как выполнить SumProduct, и использование предложения WHERE позволит вам ограничить поле датой ...

SELECT
   SUM([tbl].data * [tbl].weight) / SUM([tbl].weight)
FROM
   [tbl]
WHERE
   [tbl].date >= '2009 Jan 01'
   AND [tbl].date < '2010 Jan 01'

Более сложная часть - это то, где вы хотите «динамически указать», какое поле является [данными] и каким полем [вес]. Краткий ответ заключается в том, что реально вам придется использовать Dynamic SQL. Что-то вроде:
- Создайте строковый шаблон
- Замените все экземпляры [tbl] .data на соответствующее поле данных
- Замените все экземпляры [tbl] .weight на соответствующее поле веса
- Выполнить строку

Динамический SQL, однако, несет в себе собственные накладные расходы. Это может не иметь значения, если запросы относительно редки или время выполнения самого запроса относительно велико. Однако если они общие и короткие, вы можете заметить, что использование динамического sql приводит к заметным накладным расходам. (Не говоря уже о том, что нужно быть осторожным с атаками SQL-инъекций и т. Д.)

РЕДАКТИРОВАТЬ:

В своем последнем примере вы выделяете три поля:

  • RecordDate
  • KPI
  • Actual

Когда [KPI ] - это «Вес Y», затем [Фактический] весовой коэффициент, который следует использовать.
Когда [KPI] - «Тонны измельченных», тогда [Фактические] - это данные, которые вы хотите агрегировать.


У меня есть следующие вопросы:

  • Есть ли другие поля?
  • Всегда ли существует только ОДИН фактический показатель на дату для одного KPI?

Причина, по которой я спрашиваю, заключается в том, что вы хотите, чтобы ваше СОЕДИНЕНИЕ всегда было только 1: 1. (Вы не хотите, чтобы 5 фактических значений объединялись с 5 весами, что дает 25 результирующих записей)

Тем не менее, небольшое упрощение вашего запроса, безусловно, возможно ...

SELECT
   SUM([baseSeries].Actual * [weightSeries].Actual) / SUM([weightSeries].Actual)
FROM
   CalcProductionRecords AS [baseSeries]
INNER JOIN
   CalcProductionRecords AS [weightSeries]
      ON [weightSeries].RecordDate = [baseSeries].RecordDate
--    AND [weightSeries].someOtherID = [baseSeries].someOtherID
WHERE
   [baseSeries].KPI = 'Tons Milled'
   AND [weightSeries].KPI = 'Weighty'

Закомментированная строка нужна только в том случае, если вам нужны дополнительные предикаты для обеспечьте соотношение 1: 1 между вашими данными и весами.


Если вы не можете гарантировать только одно значение на дату и у вас нет других полей для присоединения, вы можете немного изменить свою версию на основе sub_query .. .

19
ответ дан 30 November 2019 в 17:27
поделиться
SELECT  SUM(A * B) / SUM(A)
FROM    mytable
12
ответ дан 30 November 2019 в 17:27
поделиться

Если я понял проблему, попробуйте это

SET DATEFORMAT dmy
    declare @tbl table(A int, B int,recorddate datetime,KPI varchar(50))
    insert into @tbl 
        select 1,10 ,'21/01/2009', 'Weighty'union all 
        select 2,20,'10/01/2009', 'Tons Milled' union all
        select 3,30 ,'03/02/2009', 'xyz'union all 
        select 4,40 ,'10/01/2009', 'Weighty'union all
        select 5,50 ,'05/01/2009', 'Tons Milled'union all 
        select 6,60,'04/01/2009', 'abc' union all
        select 7,70 ,'05/01/2009', 'Weighty'union all 
        select 8,80,'09/01/2009', 'xyz' union all
        select 9,90 ,'05/01/2009', 'kws'    union all 
        select 10,100,'05/01/2009', 'Tons Milled'

    select SUM(t1.A*t2.A)/SUM(t2.A)Result  from  
                   (select RecordDate,A,B,KPI from @tbl)t1 
        inner join(select RecordDate,A,B,KPI from @tbl t)t2
        on t1.RecordDate = t2.RecordDate
        and t1.KPI = t2.KPI
1
ответ дан 30 November 2019 в 17:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: