针对相同数据的不同列的不同平均值的SQL查询

时间:2014-08-07 05:01:14

标签: mysql sql sql-server

我正在研究的S​​QL挑战是构建一个查询来显示一个人的名字以及他们在一列中超过10次迭代数据的平均表现以及他们在下一列中平均超过50次迭代的数据。当然按名称分组。迭代按顺序进行,因此个人过去10的平均值将是该个体的10个最高ID号的平均分数。原始数据集如下所示:

ID, Name, Score
1, Joe, 10
2, Bob, 13
3, Joe, 9
4, Kim, 6
5, Rob, 8
6, Han, 9
7, Kim, 12

这样大约有1000行,大约有50个名字。最终目标是运行一个返回如下内容的查询:

Name, AvgPast10, AvgPast50
Bob, 8, 10
Joe, 7, 9
Kim, 6, 10
Han, 9, 6
Rob, 7, 5

当我尝试这样做时,我意识到可能有不同的方法来做到这一点。也许自我联合回到自己,也许是嵌套的select语句。我试过并意识到我正在进入我的脑海。此外,我的老板是查询优化的真正坚持者。出于某种原因,他鄙视嵌套的select语句。如果我需要它们,那么我最好有一个令人信服的理由,或者至少对如何在查询中构建优化有所了解。

2 个答案:

答案 0 :(得分:1)

不可否认,这个使用嵌套的select(或子查询):

SELECT Name, AVG(CASE WHEN Rank <= 10 THEN Score END) AvgPast10,
  AVG(CASE WHEN Rank <= 50 THEN Score END) AvgPast50
  FROM (
     SELECT Name, 
     @rank := IF(@Name = Name, @rank+1, 1) as Rank,
     @Name := Name, Score
     FROM tbl
     ORDER BY Name, ID DESC
     ) A
GROUP BY Name

为了简单起见,请参阅使用过去3和过去5的 Demo

答案 1 :(得分:0)

你的样本非常小,所以我在下面使用了2和50,但希望无论数字或平均数是多少,这个过程都是明确的

| NAME | AVG_2 | AVG_50 |
|------|-------|--------|
|  Bob |    13 |     13 |
|  Han |     9 |      9 |
|  Joe |     9 |    9.5 |
|  Kim |    12 |      9 |
|  Rob |     8 |      8 |


SELECT
      name
    , sum_2 / (count_2 * 1.0)   AS avg_2
    , sum_50 / (count_50 * 1.0) AS avg_50
FROM (
            SELECT
                  name
                , COUNT(CASE
                        WHEN rn <= 2 THEN score END)  count_2
                , SUM(CASE
                        WHEN rn <= 2 THEN score END)  sum_2
                , COUNT(CASE
                        WHEN rn <= 50 THEN score END) count_50
                , SUM(CASE
                        WHEN rn <= 50 THEN score END) sum_50
            FROM (
                        SELECT
                              *
                            , ROW_NUMBER() OVER (PARTITION BY name ORDER BY ID DESC) AS rn
                        FROM Scores
                  ) x
            GROUP BY
                  name
      ) y
ORDER BY
      name

如果观察次数小于所需数量(例如,计数为20但平均值为50),我不确定您想要做什么,我在本例中使用了实际计数。

请参阅:http://sqlfiddle.com/#!3/84cf6/2