1

NCAAアスリートと、それらのアスリートが高校に通った場所に関する情報があります。高校に通ったNCAAアスリートの数で高校をランク付けしたいと思います。

、、、、、、があります。players_ は学校(名前、場所、タイプ(大学、高校))を表し、aは(男子サッカー、女子バレーボール)の特定のチームを表し、aは特定の1年(2012年の男子サッカーチーム)を表します。アスリートの経歴情報(彼らが育った場所、彼らが通った高校、彼らの名前)、aはaを表します(年、サイズ、体重、位置の統計)。teamsteam_historiesaccountsplayer_to_team_historiesaccountteamaccountteam_historyteamplayerplayer_to_team_historyplayerteam_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_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、これを簡単にするためにRailsを使用できる場所はありますか?

バージョン

Rails 3.2.1
Ruby 1.9.2 
4

2 に答える 2

0

これはARELを使用して実行できますが、多くの掘り下げが必要になります。しかし、サブクエリを非常に簡単にするために過去に使用したのは、 squeelを使用することです

「Squeelを使用すると、ActiveRecordの下にあるARelの素晴らしさをより利用しやすくすることで、より少ない文字列とより多くのRubyでActiveRecordクエリを記述できます。」

于 2012-12-05T19:09:02.440 に答える
0

これはあなたの質問に正確に答えるものではありませんが、問題を解決するためにこれを試すことをお勧めします。

既存のSQLクエリを取得し、SQLテンプレートgemを使用します。

Yesql に基づくYayqlのようなものを試すことができますが、任意のテキストまたはSQLテンプレートエンジンで問題ありません。

于 2017-04-29T11:28:15.220 に答える