Как рассчитать агрегированную функцию продукта в SQL Server

У меня есть таблица с 2 столбцами:

No.  Name    Serial
1    Tom       1
2    Bob       5
3    Don       3
4    Jim       6

Я хочу добавить столбец, содержимое которого умножается на последовательный столбец, например:

No.  Name    Serial   Multiply
1    Tom       2         2
2    Bob       5         10
3    Don       3         30
4    Jim       6         180

Как я могу это сделать?


person Tommy Sayugo    schedule 10.06.2015    source источник
comment
Как именно рассчитывается столбец умножения?   -  person kojow7    schedule 10.06.2015
comment
Вы не должны хранить вычисляемый столбец в базе данных. Вместо этого создайте вложенный оператор выбора, чтобы вычислить значение для вас.   -  person kojow7    schedule 10.06.2015


Ответы (2)


О, это боль. Большинство баз данных не поддерживают функцию product агрегирования. Вы можете эмулировать его с журналами и полномочиями. Итак, что-то вроде этого может работать:

select t.*,
       (select exp(sum(log(serial)))
        from table t2
        where t2.no <= t.no
       ) as cumeProduct
from table t;

Обратите внимание, что log() может называться ln() в некоторых базах данных. Кроме того, это работает для положительных чисел. Существуют варианты обработки отрицательных чисел и нулей, но это усложняет ответ (и все образцы данных положительные).

person Gordon Linoff    schedule 10.06.2015
comment
@TommySayugo - нет, вы можете ссылаться на одну и ту же таблицу несколько раз в запросе. При этом следует использовать псевдонимы (t, t2), чтобы указать, на какой экземпляр таблицы вы ссылаетесь. - person Damien_The_Unbeliever; 10.06.2015

Создание агрегата CLR не так уж и плохо. Я накрутил примерно за 5 минут:

[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.Native)]
public struct Product
{
    private SqlDouble _p;
    public void Init()
    {
        this._p = new SqlDouble(1);
    }

    public void Accumulate(SqlDouble Value)
    {
        this._p *= Value;
    }

    public void Merge (Product Group)
    {
        this._p *= Group._p;
    }

    public SqlDouble Terminate ()
    {
        // Put your code here
        return _p;
    }
}

Получив это, вы можете использовать методы, обычно используемые для текущей суммы (например, треугольное соединение или определение окна, которое ограничивает строки, в зависимости от вашей версии sql).

person Ben Thul    schedule 10.06.2015