SQL中的组合聚合和非聚合查询

时间:2013-05-13 21:35:58

标签: sql aggregate-functions

不确定如何使用此问题,但我希望将聚合查询应用于多行。希望一个例子可以让这更容易。假设我有以下数据:

  player  | year | games
-------------------------
ausmubr01 | 2006 | 139
ausmubr01 | 2007 | 117
bondsba01 | 2006 | 130
bondsba01 | 2007 | 126
stairma01 | 2006 | 26
stairma01 | 2006 | 77
stairma01 | 2006 | 14
stairma01 | 2007 | 125

对于每年的每位球员,我想计算他们的“职业年”,即他们一直在玩的年数:

  player  | year | games | cyear
 --------------------------------
ausmubr01 | 2006 | 139   |  1
ausmubr01 | 2007 | 117   |  2
bondsba01 | 2006 | 130   |  1
bondsba01 | 2007 | 126   |  2
stairma01 | 2006 | 26    |  1
stairma01 | 2006 | 77    |  2
stairma01 | 2006 | 14    |  3
stairma01 | 2007 | 125   |  4

将此转换表达为SELECT player, year, games, year - min(year) + 1 as cyear FROM baseball GROUP by player是很自然的,但由于聚合查询的规则,表达式仅针对每个组进行一次评估:

  player  | year | games | cyear
 --------------------------------
ausmubr01 | 2006 | 139   |  1
bondsba01 | 2006 | 130   |  1
stairma01 | 2006 | 26    |  1

我如何一般地克服这个问题(即不仅仅是针对这种情况,而是每当我想要执行一个算术运算,结合现有的列和用聚合函数计算的单个每组数)?

4 个答案:

答案 0 :(得分:4)

您可以在职业年度使用ROW_NUMBER

SELECT player, year, games,
       cyear = ROW_NUMBER () OVER (PARTITION BY player ORDER BY year),
       gamesPerMax = 1.0 * games / MAX(games) OVER (PARTITION BY player)
FROM dbo.TableName

Demo

查看功能强大的OVER clause

答案 1 :(得分:3)

一种简单的方法是将每个玩家的起始年度计算为聚合查询,并将数据与原始数据相结合。这些“基于序列”的查询通常很难以基于集合的语言表达:(

WITH tmp as (
  select player, min(year) as minyear 
  from table 
  group by player
);

select t.*, t.year - t.minyear + 1 as cyear
from table as t, tmp
where t.player = tmp.player;

答案 2 :(得分:1)

如果您没有WITH或OVER,那么......获得一个真正的数据库。 如果做不到这一点,您可以使用子查询来完成:

SELECT t.*, t.year - subtable.minyear + 1 AS cyear
FROM table AS t
JOIN (
  select player, min(year) as minyear 
  from table 
  group by player
) AS SubTable
ON T.player = SubTable.player

答案 3 :(得分:0)

只需使用多个组...并在所需的字段上求和

GROUP BY player, year