Average在SQL Server中计算加权平均值

Average在SQL Server中计算加权平均值,sql,sql-server,tsql,Sql,Sql Server,Tsql,有人能解释一下为什么AVG函数在我的代码中给我一个加权平均值吗 SELECT s.stud_id, s.country, SUM(e.paid) AS totalpaid INTO #totalpaid FROM oc.students AS s JOIN oc.enrollment AS e ON s.stud_id = e.stud_id GROUP BY s.country ,s.stud_id; SELECT DISTINCT s.country, ROUND

有人能解释一下为什么AVG函数在我的代码中给我一个加权平均值吗

SELECT s.stud_id, s.country, SUM(e.paid) AS totalpaid
    INTO #totalpaid 
    FROM oc.students AS s
    JOIN oc.enrollment AS e ON s.stud_id = e.stud_id
GROUP BY s.country ,s.stud_id;

SELECT DISTINCT s.country, ROUND(AVG(t.totalpaid) OVER (PARTITION BY s.country),0) AS avg_country
    FROM #totalpaid t
    JOIN oc.students s ON t.stud_id = s.stud_id
    JOIN oc.enrollment e ON e.stud_id = s.stud_id; 
例如,在马耳他,12名学生参加了1门课程,支付了45欧元,837名学生参加了7门课程,总共支付了294欧元。我想对平均值进行一个简单的45+294/2计算,但是系统的计算结果是1*45+7*294/8。我做错了什么?

因为您要加入两次表

通过组合INSERT和SELECT语句,您的查询相当于:

SELECT
  DISTINCT s.country, 
  ROUND(AVG(t.totalpaid) OVER (PARTITION BY s.country),0) AS avg_country
FROM (
  SELECT s.stud_id, s.country, SUM(e.paid) AS totalpaid
  FROM oc.students AS s
  JOIN oc.enrollment AS e ON s.stud_id = e.stud_id
  GROUP BY s.country ,s.stud_id    
) t
JOIN oc.students s ON t.stud_id = s.stud_id
JOIN oc.enrollment e ON e.stud_id = s.stud_id

在那里,您可以清楚地看到表中学生和注册被联接了两次。这将产生一个扭曲的平均函数。

因为您要连接两次表

通过组合INSERT和SELECT语句,您的查询相当于:

SELECT
  DISTINCT s.country, 
  ROUND(AVG(t.totalpaid) OVER (PARTITION BY s.country),0) AS avg_country
FROM (
  SELECT s.stud_id, s.country, SUM(e.paid) AS totalpaid
  FROM oc.students AS s
  JOIN oc.enrollment AS e ON s.stud_id = e.stud_id
  GROUP BY s.country ,s.stud_id    
) t
JOIN oc.students s ON t.stud_id = s.stud_id
JOIN oc.enrollment e ON e.stud_id = s.stud_id

在那里,您可以清楚地看到表中学生和注册被联接了两次。这将产生一个扭曲的平均函数。

在您的第二个查询中,当您将临时表连接回注册时,它将为每个类生成一行;这就是totalpaid列中的多个值的来源

第二个查询没有使用任何不在临时表中的列,因此您根本不需要这些连接。这会产生你想要的东西

SELECT 
  t.country, 
  ROUND(AVG(t.totalpaid) OVER (PARTITION BY t.country),0) AS avg_country
FROM #totalpaid t
GROUP BY 
  t.country;

在第二个查询中,当您将临时表加入到注册中时,它将为每个类生成一行;这就是totalpaid列中的多个值的来源

第二个查询没有使用任何不在临时表中的列,因此您根本不需要这些连接。这会产生你想要的东西

SELECT 
  t.country, 
  ROUND(AVG(t.totalpaid) OVER (PARTITION BY t.country),0) AS avg_country
FROM #totalpaid t
GROUP BY 
  t.country;

与此同时,我找到了解决办法:

 SELECT
      country,
      ROUND(AVG(totalpaid) OVER (PARTITION BY country),0) AS avg_country
    FROM #totalpaid;

超级简单:

与此同时,我找到了解决方案:

 SELECT
      country,
      ROUND(AVG(totalpaid) OVER (PARTITION BY country),0) AS avg_country
    FROM #totalpaid;

超级简单:

对于提出问题的当前用户和具有类似问题的未来用户,纯代码答案往往被认为是低质量的。对您的解决方案的解释为您的答案增加了重要的价值。对于提出问题的当前用户和具有类似问题的未来用户,纯代码答案往往被认为是低质量的。对你的解决方案的解释会给你的答案增加很大的价值。我明白了。但是如果没有这些,我怎么能解决这个问题呢?很抱歉,如果它是非常基本的,但我不能看到其他方式。你能给我一个提示吗?我明白了。但是如果没有这些,我怎么能解决这个问题呢?很抱歉,如果它是非常基本的,但我不能看到其他方式。你能给我一个提示吗?是的,你完全正确。但是,您编写的代码给了我一个错误。这是有效的:{选择DISTINCT.country,ROUNDAVGt.totalpayment按t.country划分,0作为t.country按t.country,t.totalpayment划分的TotalPayment t组中的avg_country;}但是如果没有DISTINCT,又会有多个值。好的,同时我找到了解决方案,我完全太复杂了。非常感谢。是的,你完全正确。但是,您编写的代码给了我一个错误。这是有效的:{选择DISTINCT.country,ROUNDAVGt.totalpayment按t.country划分,0作为t.country按t.country,t.totalpayment划分的TotalPayment t组中的avg_country;}但是如果没有DISTINCT,又会有多个值。好的,同时我找到了解决方案,我完全太复杂了。谢谢。