2011-03-13 72 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