簡體   English   中英

Rails中的復雜MySQL查詢

[英]Complex MySQL Query in Rails

我們提供有關NCAA運動員以及這些運動員在哪里上高中的信息。 我們想按參加過該高中的NCAA運動員的數量來對高中排名。

我們有playersteamsteam_historiesaccountsplayer_to_team_histories account代表學校(名稱,位置,類型(大學,高中)), team描述account中的特定球隊(男子足球,女子排球), team_history代表特定team一年(2012年男子足球)隊),一個player代表了運動員的傳記信息(在那里長大,他們出席了高中,他們的名字),一個player_to_team_history代表playerteam_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

通過獲取與我們感興趣的所有球員相關的與高中相關的player_to_team_historyplayer_to_team_history accounts.AccountTypeId = 1 ),我們可以找出隊友參加過的高中,並按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執行select_by_sql ,還有什么地方可以使用Rails select_by_sql此操作?

版本

Rails 3.2.1
Ruby 1.9.2 

這可以使用AREL完成,但是需要大量挖掘。 但是我過去使子查詢更容易使用的是使用squeel

“ Squeel通過使位於ActiveRecord下的ARel令人敬畏,可以​​使用更少的字符串和更多的Ruby編寫ActiveRecord查詢。”

盡管這不能完全回答您的問題,但我建議您嘗試一下以解決您的問題。

進行現有的SQL查詢並使用SQL模板gem。

你可以嘗試像Yayql這是基於Yesql ,但任何文本或SQL模板引擎都行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM