2012-12-05 32 views
1

我們掌握了有關NCAA運動員以及那些運動員去高中的信息。我們想根據參加高中的NCAA運動員人數來排列高中。Rails中複雜的MySQL查詢

我們有playersteamsteam_historiesaccountsplayer_to_team_histories。一個account代表一個學校(名稱,地點,類型(大學,高中)),一個team描述了一個特定的隊伍在account(男子足球,女子排球),team_history代表特定的一年team(2012年男子足球團隊),player代表運動員(他們在哪裏長大,他們上哪所高中,他們的名字)的傳記信息,player_to_team_history代表在team_history(年份,大小,體重,位置的統計數據)。

我已經制定了以下MySQL查詢來提取每個高中在特定大學的運動員人數排名。下面我將打破查詢,從最內層的語句:

SELECT WrappedQuery.rank FROM 
(SELECT 
    @rownum := @rownum+1 AS rank, q.Name, q.id 
FROM  
    (SELECT @rownum := 0) counter, 
    (SELECT 
     Accounts.id, Accounts.Name, COUNT(Accounts.Name) AS count 
    FROM 
     player_to_team_histories 
    INNER JOIN team_histories ON team_histories.id = player_to_team_histories.team_history_id 
    INNER JOIN teams ON teams.id = team_histories.team_id 
    INNER JOIN accounts ON accounts.id = teams.account_id 
    WHERE 
     accounts.AccountTypeId = 1 AND player_id IN (SELECT 
      player_id 
     FROM 
      player_to_team_histories 
     WHERE 
      player_to_team_histories.not_valid IS NULL AND team_history_id = (SELECT 
       team_history_id 
      FROM 
       player_to_team_histories 
      INNER JOIN team_histories ON team_histories.id = player_to_team_histories.team_history_id 
      WHERE 
       player_to_team_histories.id = 574651)) 
    GROUP BY Accounts.Name 
    ORDER BY count DESC) q) WrappedQuery 
WHERE WrappedQuery.id = 7661 

團隊歷史ID

SELECT 
    team_history_id 
FROM 
    player_to_team_histories 
     INNER JOIN 
    team_histories ON team_histories.id = player_to_team_histories.team_history_id 
WHERE 
    player_to_team_histories.id = 574651 

這提取team_history_id爲高校團隊,我們感興趣的是,這使得我們可以爲我們選擇的玩家找到隊友(由player_to_team_history.id = 574651標識),因爲所有的隊友都擁有相同的team_history_id。

隊友

SELECT 
    player_id 
FROM 
    player_to_team_histories 
WHERE 
    player_to_team_histories.not_valid IS NULL AND team_history_id = (SELECT 
     team_history_id 
    FROM 
     player_to_team_histories 
      INNER JOIN 
     team_histories ON team_histories.id = player_to_team_histories.team_history_id 
    WHERE 
     player_to_team_histories.id = 574651) 

我們使用team_history_id讓所有的玩家選擇的隊友。然後我們使用球員找到他們的高中。

高中隊

SELECT 
    Accounts.id, Accounts.Name, COUNT(Accounts.Name) AS count 
FROM 
    player_to_team_histories 
     INNER JOIN 
    team_histories ON team_histories.id = player_to_team_histories.team_history_id 
     INNER JOIN 
    teams ON teams.id = team_histories.team_id 
     INNER JOIN 
    accounts ON accounts.id = teams.account_id 
WHERE 
    accounts.AccountTypeId = 1 AND player_id IN (SELECT 
     player_id 
    FROM 
     player_to_team_histories 
    WHERE 
     player_to_team_histories.not_valid IS NULL AND team_history_id = (SELECT 
      team_history_id 
     FROM 
      player_to_team_histories 
       INNER JOIN 
      team_histories ON team_histories.id = player_to_team_histories.team_history_id 
     WHERE 
      player_to_team_histories.id = 574651)) 
GROUP BY Accounts.Name 
ORDER BY count DESC 

通過抓住與高中(accounts.AccountTypeId = 1)對我們感興趣的所有玩家相關的player_to_team_history,我們可以找出哪些高中隊友在玩,他們組accounts.id,然後根據每個組的數量進行排序,從而給我們列出了哪些高中在大學名單上擁有最多球員的排序列表。

排名

SELECT WrappedQuery.rank FROM 
(SELECT 
    @rownum := @rownum+1 AS rank, q.Name, q.id 
FROM  
    (SELECT @rownum := 0) counter, 
    (SELECT 
     Accounts.id, Accounts.Name, COUNT(Accounts.Name) AS count 
    FROM 
     player_to_team_histories 
    INNER JOIN team_histories ON team_histories.id = player_to_team_histories.team_history_id 
    INNER JOIN teams ON teams.id = team_histories.team_id 
    INNER JOIN accounts ON accounts.id = teams.account_id 
    WHERE 
     accounts.AccountTypeId = 1 AND player_id IN (SELECT 
      player_id 
     FROM 
      player_to_team_histories 
     WHERE 
      player_to_team_histories.not_valid IS NULL AND team_history_id = (SELECT 
       team_history_id 
      FROM 
       player_to_team_histories 
      INNER JOIN team_histories ON team_histories.id = player_to_team_histories.team_history_id 
      WHERE 
       player_to_team_histories.id = 574651)) 
    GROUP BY Accounts.Name 
    ORDER BY count DESC) q) WrappedQuery 
WHERE WrappedQuery.id = 7661 

我們通過編號我們的排名中的每一行,抓住行,我們感興趣的是玩完了。在這種情況下,我們感興趣的是高中,其ACCOUNTID的7661.這是所選擇的球員參加的高中,這將告訴我們,在所有爲當前大學球員貢獻球員的高中中,我們所選擇的球員在高中排名。

如何在Rails的

做到這一點。這就是我很失落。我將如何做這些嵌套連接/子查詢和結果排名?

我完全明白這可能是一個可怕的方法來解決這個問題。將它分解爲多個查詢並將所有內容拼湊在一起返回Rails會更好嗎?

缺少做select_by_sql,有沒有我可以使用Rails使這更容易的地方?

VERSIONS

Rails 3.2.1 
Ruby 1.9.2 

回答

0

這可以通過使用AREL可以做到,但將需要大量的挖掘。但我過去使用子查詢更容易的方法是使用squeel

「Squeel允許您使用更少的字符串和更多的Ruby編寫ActiveRecord查詢,讓ActiveRecord下的ARel更加易於訪問「。

0

儘管這並不完全解答您的問題,但我會建議您嘗試解決您的問題。

帶上您現有的SQL查詢並使用SQL模板gem。

您可以嘗試類似Yayql 這是基於Yesql,但任何文本或SQL模板引擎會做。