Функция AVG вычисляет правильно в SELECT с GROUP BY, но не с UPDATE для некоторых записей - PullRequest
0 голосов
/ 28 мая 2019

У меня есть простая таблица с подробными данными, в которой перечислены номер клиента и соответствующая оценка в формате с плавающей запятой. Когда я делаю среднее значение, используя AVG с группой По клиенту в Select, он правильно рассчитывает средние значения оценки для каждого клиента, но если хочетобновите основную таблицу, указав номер клиента со средней оценкой, используя исходный выбор. Мой запрос на обновление неправильно рассчитывает средние значения для некоторых клиентов, поэтому мне интересно, где может быть ошибка.

Попытка использовать приведение кдесятичный с двумя десятичными точками в запросе на обновление в выбранной части, поскольку данные имеют 17 десятичных знаков, но проблема остается.Это всего лишь тест для 16 записей, но мне нужно решить проблему, прежде чем продолжить.

--AVG used only in Select correctly does the average calculation from the detail (child) table SELECT sd.customer, AVG(score) AS avg_score_group from score_detail as sd
        JOIN score_master as sm ON sd.customer = sm.customer
        GROUP BY sd.customer
    -- Using AVG to actually update the master table with averages from child 
    -- table has incorrect calculations for some grouped records
        UPDATE score_master
        SET avg_score = t.avg_score_group
        FROM (
        SELECT AVG(score) AS avg_score_group from score_detail as sd
        JOIN 
        score_master as sm
        ON
        sd.customer = sm.customer
        GROUP BY sd.customer
        ) AS t
    --Let us explore master table
        SELECT * FROM  score_master;
--Table structures:
CREATE TABLE [dbo].[score_detail](
[customer] [float] NULL,
[score] [float] NULL
) ON [PRIMARY]


CREATE TABLE [dbo].[score_master](
[customer] [float] NULL,
[avg_score] [float] NULL
) ON [PRIMARY]
-- Data to calculate average has 17 Decimal points:
INSERT [dbo].[score_detail] ([customer], [score]) VALUES (2, -0.07216878364870323)

Я ожидаю, что те же результаты в таблице «Только для выбора из сведений» появятся в запросе на обновление длямастер таблицы, но некоторые не верны, т.е. клиенты 4 и 7:

Cust No -   Avg in Detail table     - Avg in Master table  
2           -0.0681                 -0.0681  
4            0.0000                  0.1127  
7            0.0184                 -0.0681  
16           0.1127                  0.1127

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

Я считаю, что строки, которые вы выбрали для обновления в операторе UPDATE, не выбраны правильно, вы должны соединить обновленную таблицу и таблицу со средними значениями, используя INNER JOIN (или просто JOIN, что на самом деле INNER JOIN):

    UPDATE score_master
    SET avg_score = t.avg_score_group
    FROM 
    (
       SELECT AVG(score) AS avg_score_group , sd.customer AS customer
       FROM score_detail as sd
       JOIN score_master as sm
       ON
       sd.customer = sm.customer
       GROUP BY sd.customer          
    ) AS t
    JOIN score_master ON score_master.customer = t.customer

Вот SQL-скрипка: http://sqlfiddle.com/#!18/50cf30/17

0 голосов
/ 28 мая 2019

Я не вижу предложения where в подзапросе, используемом в обновлении, и это выглядит неправильно ... корреляции нет, и, следовательно, нет гарантии, какое значение выбрано из результатов подзапроса.Попробуйте переписать ваш запрос на обновление следующим образом:

UPDATE score_master
SET avg_score = (
    SELECT AVG(score)
    FROM score_detail
    WHERE score_detail.customer = score_master.customer
)

Сказав это, я бы порекомендовал вам не хранить значения, которые можно рассчитать по требованию.Вместо этого создайте представление для средних значений.

...