Я отвечал на другой вопрос и столкнулся с каким-то странным результатом. Результаты использования агрегата продукта (без CLR) были разными при использовании в SELECT и UPDATE.UPDATE с результатом агрегата продукта без CLR
Это упрощен от первоначального вопроса минимально воспроизвести проблему:
GroupKey RowIndex A
----------- ----------- -----------
25 1 5
25 2 6
25 3 NULL
26 1 3
26 2 4
26 3 NULL
Цель для каждого ключа группы для обновления A
столбца каждой строки с RowIndex = 3
к произведению A
столбцов каждая строка с RowIndex IN (1, 2)
, так что это будет производить следующие изменения:
GroupKey RowIndex A
----------- ----------- -----------
25 3 30
26 3 12
так что это код, который я использовал:
UPDATE T SET
A = Products.Product
FROM @Table T
INNER JOIN (
SELECT
GroupKey,
EXP(SUM(LOG(A))) AS Product
FROM @Table
WHERE RowIndex IN (1, 2)
GROUP BY
GroupKey
) Products
ON Products.GroupKey = T.GroupKey
WHERE T.RowIndex = 3
SELECT * FROM @Table WHERE RowIndex = 3
Который затем произвел совсем по одному результаты:
GroupKey RowIndex A
----------- ----------- -----------
25 3 29
26 3 12
Если я просто запустить подзапрос, я вижу правильные значения.
GroupKey Product
----------- ----------------------
25 30
26 12
Вот полный скрипт, с помощью которого можно легко играть. Я не могу понять, откуда это происходит.
DECLARE @Table TABLE (GroupKey INT, RowIndex INT, A INT)
INSERT @Table VALUES (25, 1, 5), (25, 2, 6), (25, 3, NULL), (26, 1, 3), (26, 2, 4), (26, 3, NULL)
SELECT * FROM @Table
SELECT
GroupKey,
EXP(SUM(LOG(A))) AS Product
FROM @Table
WHERE RowIndex IN (1, 2)
GROUP BY
GroupKey
UPDATE T SET
A = Products.Product
FROM @Table T
INNER JOIN (
SELECT
GroupKey,
EXP(SUM(LOG(A))) AS Product
FROM @Table
WHERE RowIndex IN (1, 2)
GROUP BY
GroupKey
) Products
ON Products.GroupKey = T.GroupKey
WHERE T.RowIndex = 3
SELECT * FROM @Table WHERE RowIndex = 3
Вот некоторые ссылки я натолкнулась:
- Non-CLR Совокупные: http://michaeljswart.com/2011/03/the-aggregate-function-product/
- Оригинальный вопрос: Set one row fields as a multiplication of 2 others
Конечно, это также означает, что 'round' поможет немного. Однако это все еще ненадежно. – Luaan
Интересно, хотя в моем примере, если я просто изменяю тип данных своей таблицы на FLOAT, ошибка округления не возникает, но простой метод cast/convert для float до 'LOG' не помогает. –
@JasonW - ошибка округления, но для * display *, 'float', достаточно близкий к' 30', будет преобразован в * строку * '30', тогда как когда мы попросим преобразовать этот' float' в ' int', вещи немного более строгие. –