У меня есть простая подробная таблица, в которой указан номер клиента и соответствующий балл в формате с плавающей запятой, когда я делаю среднее значение, используя 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
Я не вижу предложения where в подзапросе, используемом в обновлении, и это выглядит неправильно... нет корреляции и, следовательно, нет гарантии, какое значение будет выбрано из результатов подзапроса. Попробуйте переписать запрос на обновление следующим образом:
UPDATE score_master
SET avg_score = (
SELECT AVG(score)
FROM score_detail
WHERE score_detail.customer = score_master.customer
)
Сказав это, я бы рекомендовал вам не хранить значения, которые можно вычислить по запросу. Вместо этого создайте представление для средних значений.
@Renaud Было бы здорово, если бы вы сейчас могли пометить предложение как ответ, потому что именно так другие находят ответы на подобные вопросы в будущем.
Я считаю, что строки, которые вы выбрали для обновления в операторе 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
Теперь я вижу, что я пропустил, я ценю ваш ответ
Отличное объяснение, я попробовал и теперь делаю то, что ожидалось