SQL为什么我必须将GroupBy与OrderBy一起使用?

时间:2014-07-04 18:01:59

标签: sql sql-server group-by sql-order-by

大家好,我有一系列不同的足球比赛数据。

我想要做的是为特定联赛取一些平均值和一些游戏的总和。我按日期排序以获取最新的匹配,然后选择Top(X),因为用户定义了他们想要选择的数量。

但是我不明白为什么我必须使用GroupBy,因为我没有任何东西可以分组,只是想要所有这些的平均值和总和。

我的查询如下,

ALTER PROCEDURE [dbo].[isp_CompetitionSummary_GenerateByMatches]
@CompetitionId varchar(4),
@Matches int
AS
BEGIN
SELECT TOP (@Matches)
[Date],
@CompetitionId AS CompetitionId,
Sum(HomeGoals) AS HomeGoals,
Sum(AwayGoals) AS AwayGoals,
Sum(HalfTimeHomeGoals) AS HalfTimeHomeGoals,
Sum(HalfTimeAwayGoals) AS HalfTimeAwayGoals,
Sum(HomeTeamCorners) AS HomeCorners,
Sum(AwayTeamCorners) AS AwayCorners,
Sum(HomeTeamFouls) AS HomeFouls,
Sum(AwayTeamFouls) AS AwayFouls,
Sum(HomeTeamYellows) AS HomeYellows,
Sum(AwayTeamYellows) AS AwayYellows,
Sum(HomeTeamReds) AS HomeReds,
Sum(AwayTeamReds) AS AwayReds,
AVG(CAST(HomeGoals AS FLOAT)) AS AvgHomeGoals,
AVG(CAST(AwayGoals AS FLOAT)) AS AvgAwayGoals,
AVG(CAST(HalfTimeHomeGoals AS FLOAT)) AS AvgHalfTimeHomeGoals,
AVG(CAST(HalfTimeAwayGoals AS FLOAT)) AS AvgHalfTimeAwayGoals,
AVG(CAST(HomeTeamCorners AS FLOAT)) AS AvgHomeCorners,
AVG(CAST(AwayTeamCorners AS FLOAT)) AS AvgAwayCorners,
AVG(CAST(HomeTeamFouls AS FLOAT)) AS AvgHomeFouls,
AVG(CAST(AwayTeamFouls AS FLOAT)) AS AvgAwayFouls,
AVG(CAST(HomeTeamYellows AS FLOAT)) AS AvgHomeYellows,
AVG(CAST(AwayTeamYellows AS FLOAT)) AS AvgAwayYellows,
AVG(CAST(HomeTeamReds AS FLOAT)) AS AvgHomeReds,
AVG(CAST(AwayTeamReds AS FLOAT)) AS AvgAwayReds
FROM dbo.Match
INNER JOIN dbo.MatchDetail ON dbo.Match.Id = dbo.MatchDetail.MatchId
WHERE Div = @CompetitionId
GROUP BY [Date]
ORDER BY [Date] DESC

2 个答案:

答案 0 :(得分:1)

TOP (@Matches)不会限制您使用的数据,它只会限制结果。您将获得按日期分组的所有数据的总和和平均值,然后限制为最后@Matches个日期。

首先限制子查询中的数据,然后您可以获得这些匹配的总和和平均值。

请注意,[Date]已从选择中删除。如果要选择日期,则必须使用MAX([Date])来决定获取日期,例如最新日期。

ALTER PROCEDURE [dbo].[isp_CompetitionSummary_GenerateByMatches]
@CompetitionId varchar(4),
@Matches int
AS
BEGIN
SELECT
@CompetitionId AS CompetitionId,
Sum(HomeGoals) AS HomeGoals,
Sum(AwayGoals) AS AwayGoals,
Sum(HalfTimeHomeGoals) AS HalfTimeHomeGoals,
Sum(HalfTimeAwayGoals) AS HalfTimeAwayGoals,
Sum(HomeTeamCorners) AS HomeCorners,
Sum(AwayTeamCorners) AS AwayCorners,
Sum(HomeTeamFouls) AS HomeFouls,
Sum(AwayTeamFouls) AS AwayFouls,
Sum(HomeTeamYellows) AS HomeYellows,
Sum(AwayTeamYellows) AS AwayYellows,
Sum(HomeTeamReds) AS HomeReds,
Sum(AwayTeamReds) AS AwayReds,
AVG(CAST(HomeGoals AS FLOAT)) AS AvgHomeGoals,
AVG(CAST(AwayGoals AS FLOAT)) AS AvgAwayGoals,
AVG(CAST(HalfTimeHomeGoals AS FLOAT)) AS AvgHalfTimeHomeGoals,
AVG(CAST(HalfTimeAwayGoals AS FLOAT)) AS AvgHalfTimeAwayGoals,
AVG(CAST(HomeTeamCorners AS FLOAT)) AS AvgHomeCorners,
AVG(CAST(AwayTeamCorners AS FLOAT)) AS AvgAwayCorners,
AVG(CAST(HomeTeamFouls AS FLOAT)) AS AvgHomeFouls,
AVG(CAST(AwayTeamFouls AS FLOAT)) AS AvgAwayFouls,
AVG(CAST(HomeTeamYellows AS FLOAT)) AS AvgHomeYellows,
AVG(CAST(AwayTeamYellows AS FLOAT)) AS AvgAwayYellows,
AVG(CAST(HomeTeamReds AS FLOAT)) AS AvgHomeReds,
AVG(CAST(AwayTeamReds AS FLOAT)) AS AvgAwayReds
FROM (
  SELECT TOP (@Matches) *
  FROM dbo.Match
  INNER JOIN dbo.MatchDetail ON dbo.Match.Id = dbo.MatchDetail.MatchId
  WHERE Div = @CompetitionId
  ORDER BY [Date] DESC
) x

注意:使用聚合时,查询始终是分组的。通过省略GROUP BY并仍在查询中使用聚合,整个集合将是一个组。

答案 1 :(得分:0)

您想要每个日期的总和和平均值。 IE浏览器。 "按"分组日期。这正是你想要的,所以你必须按日期分组。

事实上,每当你在选择列表中使用聚合函数时,如果你还在不使用聚合的情况下选择一个字段,你必须按那些非聚合列进行分组,因为这实际上就是你的做。

您选择了多个SUM并平均PER DATE(而不是整个表格)。因此,您正在分组。

此外,它与您使用ORDER BY的事实无关。 GROUP BY是必需的,因为您在一些字段中使用聚合函数,同时还选择非聚合列。