2011-03-13 26 views
1

我有一个项目棒球调查统计表,这个表有很多字段,但我关心的是playerID,pos(位置),G (游戏)SQL:max(count((x))

这张表是历史性的,所以它包含多个行,每playerID(每年一个)。我想要做的是返回一个玩家在他的职业生涯中发挥最大的位置。

首先,我需要做的成像是按照playerID计算每个位置的游戏数,然后返回它的最大值,这是如何在SQL中完成的?我正在使用SQL Server。 ,可能存在关系的情况,那么max可以做什么?

+0

你想尝试一下就像找到排名?选择RANK()(按玩家顺序按游戏分区划分分区) – JoshRoss 2011-03-13 03:46:16

+0

游戏可能来自cte或可能只是计数(*)。 – JoshRoss 2011-03-13 03:56:31

回答

1

在SQL中,我相信这样做。鉴于需要两次相同的子查询,我希望将其作为存储过程将会更有效。

SELECT MaxGamesInAnyPosition.playerID, GamesPerPosition.pos 
    FROM (
     SELECT playerID, Max(totalGames) As maxGames 
     FROM (
      SELECT playerID, pos, SUM(G) As totalGames 
      FROM tblStats 
      GROUP BY playerId, pos) Tallies 
     GROUP BY playerID) MaxGamesInAnyPosition 

    INNER JOIN (
     SELECT playerID, pos, SUM(g) As totalGames 
     FROM tblStats 
     GROUP BY playerID, pos) GamesPerPosition 
    ON (MaxGamesInAnyPosition.playerID=GamesPerPosition.playerId 
     AND MaxGamesInAnyPosition.maxGames=GamesPerPosition.totalGames) 
+0

我不认为这会正确处理关系,但现在为时尚晚,难以想清楚结果会如何混乱。再见。 – 2011-03-13 03:34:14

+0

如果在两个位置之间有一个联系,那么您将在该播放器的输出中有两行。如果这不可取,可以在最外面的GamesPerPosition.pos中添加一个max()或min()函数。 – joelt 2011-03-13 03:39:55

+0

另外,考虑到查询的复杂性,您可能需要考虑在应用程序中调用它的一些处理。 – joelt 2011-03-13 03:40:44

2

如果在同一个位置上的多个团队在多个场比赛球员,我会更倾向于使用sum()函数,而不是数量,除了使用一组由语句,一个子查询。请参阅代码解释。

SELECT playerID, pos, MAX(g_sum) 
FROM (
    SELECT DISTINCT playerID, pos, SUM(G) as g_sum 
    FROM player_stats 
    GROUP BY id, pos 
    ORDER BY 3 DESC 
) game_sums 
GROUP BY playerID 

这可能不是确切答案,至少这是一个不错的起点,它的工作对我的,我在10分钟内刮起了跛脚测试平台。至于max()如何处理关系:它不(至少据我所知,至少)。这取决于实际的GROUP BY声明本身,以及查询或子查询中最大值出现的位置和方式。

如果我们在GROUP BY声明中包含pos,在平局的情况下,它会向您显示球员在这些职位上的比赛位置和数量(这将是相同的数字)。在不是GROUP BY语句中,查询将与该列的最后一个给定值一起进行。所以如果位置2出现在子查询中的位置3之前,则完整查询将显示位置3作为玩家玩过最多游戏的位置。

0

看起来不漂亮,但它是直接翻译的内容我内置的LINQ to SQL中,给它一个尝试,看看是否是你想要的:

SELECT [t2].[playerID], (
    SELECT TOP (1) [t7].[pos] 
    FROM (
     SELECT [t4].[playerID], [t4].[pos], (
      SELECT COUNT(*) 
      FROM (
       SELECT DISTINCT [t5].[G] 
       FROM [players] AS [t5] 
       WHERE ([t4].[playerID] = [t5].[playerID]) AND ([t4].[pos] = [t5].[pos]) 
       ) AS [t6] 
      ) AS [value] 
     FROM (
      SELECT [t3].[playerID], [t3].[pos] 
      FROM [players] AS [t3] 
      GROUP BY [t3].[playerID], [t3].[pos] 
      ) AS [t4] 
     ) AS [t7] 
    WHERE [t2].[playerID] = [t7].[playerID] 
    ORDER BY [t7].[value] DESC 
    ) AS [pos] 
FROM (
    SELECT [t1].[playerID] 
    FROM (
     SELECT [t0].[playerID] 
     FROM [players] AS [t0] 
     GROUP BY [t0].[playerID], [t0].[pos] 
     ) AS [t1] 
    GROUP BY [t1].[playerID] 
    ) AS [t2] 
0

这是第二个答案,比我第一次踢更好的(我认为)处即可昨晚。当然更容易阅读和理解。

SELECT playerID, pos 
FROM (
    SELECT playerID, pos, SUM(G) As totGames 
    FROM tblStats 
    GROUP BY playerID, pos) Totals 
WHERE NOT (Totals.totGames < ANY(
    SELECT SUM(G) 
    FROM tblStats 
    WHERE Totals.playerID=tblStats.playerID 
    GROUP BY playerID, pos)) 

子查询,确保所有的行会抛出如果游戏总共给定位置比的游戏该玩家在任何其他位置发挥的数量。

如果有关系,则所涉及的玩家将出现所有并列行,因为没有绑定的记录将被抛出。

+0

与我的其他答案一样,我不能说这个查询如何执行。建议测试和小心。 – 2011-03-13 23:02:21