Функция AVG правильно вычисляет SELECT с GROUP BY, но не с UPDATE для некоторых записей

У меня есть простая подробная таблица, в которой указан номер клиента и соответствующий балл в формате с плавающей запятой, когда я делаю среднее значение, используя AVG с Group By Customer в Select, он правильно вычисляет средние баллы для каждого клиента, но если вы хотите обновить мастер Таблица с номером клиента и его средним баллом с использованием оригинального 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
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
0
48
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

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

Отличное объяснение, я попробовал и теперь делаю то, что ожидалось

Renaud 28.05.2019 22:15

@Renaud Было бы здорово, если бы вы сейчас могли пометить предложение как ответ, потому что именно так другие находят ответы на подобные вопросы в будущем.

SMor 29.05.2019 14:16

Я считаю, что строки, которые вы выбрали для обновления в операторе 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

Теперь я вижу, что я пропустил, я ценю ваш ответ

Renaud 28.05.2019 22:16

Другие вопросы по теме