SQL 服务器 - 如何从另一个 table 获得平均评分并将其包含在当前 table 中?
SQL Server - How to get the average rating from another table and include it in current table?
我有 table 个像这样的承包商:
SELECT [ContractorID]
,[Contractor]
,[BWSLVendorCode]
,[PhoneNumber]
,[Address]
,[PreQualification]
,[GSTNumber]
,[Avg] FROM Contractor
还有一个反馈 table,它存储每个承包商的个人评级和评论,如下所示:
SELECT [ID]
,[ContractorID]
,[Rating]
,[Comments]
,[Timestamp] FROM Feedback
我想要做的是找到每个承包商的平均评分,并将其包含在承包商 table 的平均列下。我想过使用一个函数并在计算列中调用它,但我似乎无法弄清楚如何编写所述函数。
编辑:
评分介于 1 - 5
编辑
要自动更新列值,您可以使用触发器,类似于:
CREATE TRIGGER [DBName].[updateAvg]
ON [DBName].Contractors
AFTER UPDATE,INSERT
AS
BEGIN
;WITH avgRates AS (
SELECT [ContractorID]
,SUM([Rating]) as totalRating
,COUNT(*) as noOfRatings
FROM Feedback
GROUP BY ContractorID
)
UPDATE C
SET Avg = A.totalRating / A.noOfRatings
FROM Contractor C
INNER JOIN avgRates A
ON C.ContractorID = A.ContractorID
END
我的语法在CREATE TRIGGER
上可能有误,所以你要参考官方文档:
您希望数据库中有多少 "Contractors"?每个承包商有多少反馈?我问这个是因为计算 Avg 应该在运行时完成,这样您就不必在每次输入新反馈时都重新计算...
与其将 Avg 保存在 table 中,也许您应该有一个计算它的视图并调用该视图而不是 table。比如像这样:
CREATE VIEW ContractorView AS
SELECT C.*,
((SELECT SUM(F1.Rating) FROM Feedback as F1 WHERE F1.ContractorID = C.ContractorID) / (SELECT COUNT(F2.ID) FROM Feedback as F2 WHERE F2.ContractorID = C.ContractorID)) as Avg
FROM Contractors as C
语法与此相近。 ;)
这将使用 Feedback
table 中承包商评分的平均值更新 Contractor
table 中的 Avg
列。
;with feedback_grouped
AS
(
SELECT f.ContractorID, AVG(CAST(f.rating as decimal(3,2))) as avg_rating
FROM Feedback f
GROUP BY f.ContractorID
)
UPDATE Contractor
SET avg=avg_rating
FROM Contractor c
INNER JOIN feedback_grouped
ON c.ContractorID = feedback_grouped.ContractorID
这将每个反馈按 ContractorID
分组并计算平均值 Rating
以更新原始 Contractor
table
确保 Contractor
table 中的 Avg
列是 decimal
数据类型,因为平均值可能有小数值。您可以将 (CAST(f.rating as decimal(3,2)))
更改为您在 Avg
列中使用的相同十进制数据类型。
我有 table 个像这样的承包商:
SELECT [ContractorID]
,[Contractor]
,[BWSLVendorCode]
,[PhoneNumber]
,[Address]
,[PreQualification]
,[GSTNumber]
,[Avg] FROM Contractor
还有一个反馈 table,它存储每个承包商的个人评级和评论,如下所示:
SELECT [ID]
,[ContractorID]
,[Rating]
,[Comments]
,[Timestamp] FROM Feedback
我想要做的是找到每个承包商的平均评分,并将其包含在承包商 table 的平均列下。我想过使用一个函数并在计算列中调用它,但我似乎无法弄清楚如何编写所述函数。
编辑: 评分介于 1 - 5
编辑
要自动更新列值,您可以使用触发器,类似于:
CREATE TRIGGER [DBName].[updateAvg]
ON [DBName].Contractors
AFTER UPDATE,INSERT
AS
BEGIN
;WITH avgRates AS (
SELECT [ContractorID]
,SUM([Rating]) as totalRating
,COUNT(*) as noOfRatings
FROM Feedback
GROUP BY ContractorID
)
UPDATE C
SET Avg = A.totalRating / A.noOfRatings
FROM Contractor C
INNER JOIN avgRates A
ON C.ContractorID = A.ContractorID
END
我的语法在CREATE TRIGGER
上可能有误,所以你要参考官方文档:
您希望数据库中有多少 "Contractors"?每个承包商有多少反馈?我问这个是因为计算 Avg 应该在运行时完成,这样您就不必在每次输入新反馈时都重新计算...
与其将 Avg 保存在 table 中,也许您应该有一个计算它的视图并调用该视图而不是 table。比如像这样:
CREATE VIEW ContractorView AS
SELECT C.*,
((SELECT SUM(F1.Rating) FROM Feedback as F1 WHERE F1.ContractorID = C.ContractorID) / (SELECT COUNT(F2.ID) FROM Feedback as F2 WHERE F2.ContractorID = C.ContractorID)) as Avg
FROM Contractors as C
语法与此相近。 ;)
这将使用 Feedback
table 中承包商评分的平均值更新 Contractor
table 中的 Avg
列。
;with feedback_grouped
AS
(
SELECT f.ContractorID, AVG(CAST(f.rating as decimal(3,2))) as avg_rating
FROM Feedback f
GROUP BY f.ContractorID
)
UPDATE Contractor
SET avg=avg_rating
FROM Contractor c
INNER JOIN feedback_grouped
ON c.ContractorID = feedback_grouped.ContractorID
这将每个反馈按 ContractorID
分组并计算平均值 Rating
以更新原始 Contractor
table
确保 Contractor
table 中的 Avg
列是 decimal
数据类型,因为平均值可能有小数值。您可以将 (CAST(f.rating as decimal(3,2)))
更改为您在 Avg
列中使用的相同十进制数据类型。