SQL:max(count((x))

时间:2011-03-13 02:55:08

标签: sql

我有一个棒球表,用于项目的统计数据。这张桌子上有很多字段,但我关心的是playerIDpos(位置),G(游戏)。

此表是历史记录,因此每个playerID包含多行(每年一个/ pos)。我想要做的就是回归一个球员在职业生涯中发挥最大作用的位置。

首先,我需要做的是每个位置的游戏数playerID,然后返回最大值。如何在SQL中完成?我正在使用SQL Server。在旁注中,可能存在有关系的情况,那么max会做什么呢?

4 个答案:

答案 0 :(得分:2)

如果玩家在多个游戏中在多个团队中扮演相同的位置,除了使用group by语句作为子查询之外,我更倾向于使用sum()函数而不是count 。请参阅代码以获得解释。

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语句本身,以及查询或子查询中最大值的显示位置和方式。

如果我们要在pos声明中加入GROUP BY,如果出现平局,它会显示玩家在所述位置玩过的位置和游戏数量(将是相同的数字)。在GROUP BY语句中使用 not ,查询将使用该列的最后一个给定值。因此,如果位置2出现在子查询中的位置3之前,则完整查询将显示位置3作为玩家玩过最多游戏的位置。

答案 1 :(得分: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)

答案 2 :(得分:0)

看起来不漂亮,但它直接将我在linq中构建的内容翻译成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]

答案 3 :(得分: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))

子查询确保如果在该给定位置的游戏总数小于玩家在任何其他位置玩的游戏数量,则所有行都将被抛出。

如果是关系,有问题的玩家将会显示所有绑定的行,因为没有任何绑定的记录会被抛出。