SQL Server - 如何从另一个表中获取平均评级并将其包含在当前表中?

时间:2015-11-02 20:45:38

标签: sql sql-server average calculated-columns

我有一张像这样的承包商表:

SELECT [ContractorID]
  ,[Contractor]
  ,[BWSLVendorCode]
  ,[PhoneNumber]
  ,[Address]
  ,[PreQualification]
  ,[GSTNumber]
  ,[Avg] FROM Contractor

一个反馈表,为每个承包商存储个人评级和评论,如下所示:

SELECT [ID]
  ,[ContractorID]
  ,[Rating]
  ,[Comments]
  ,[Timestamp] FROM Feedback

我想要做的是找到每个承包商的平均评级,并将其包含在Avg列下的承包商表中。我想过使用一个函数并在计算列中调用它,但我似乎无法弄清楚如何编写所述函数。

修改 评级在1 - 5之间

3 个答案:

答案 0 :(得分:1)

修改

要自动更新列值,您可以使用触发器,其类似于:

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上可能有误,所以你想参考官方文档:

CREATE TRIGGER (Transact-SQL)

答案 1 :(得分:1)

这将更新Avg表格中的Contractor列,其中包含Feedback表格中承包商评级的平均值。

;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表格

确保Avg表中的Contractor列是decimal数据类型,因为平均值可能有十进制值。您可以将(CAST(f.rating as decimal(3,2)))更改为Avg列中使用的相同十进制数据类型。

答案 2 :(得分:0)

多少"承包商"你期待在你的数据库中吗?每个承包商有多少反馈?我问这个是因为计算平均值应该在运行时完成,这样你就不必每次都有新的反馈重新计算...

不是将Avg保存在表中,也许你应该有一个计算它的视图并调用视图而不是表。比如这样:

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

语法与此类似。 ;)