1

我们有关于 NCAA 运动员的信息以及这些运动员上高中的地方。我们想根据参加上述高中的 NCAA 运动员人数对高中进行排名。

我们有players, teams, team_histories, accounts, 和player_to_team_histories。anaccount代表一所学校(名称、位置、类型(大学、高中)),ateam代表一个特定的球队account(男足、女排),ateam_history代表某个特定team的一年(2012 年男足),aplayer代表运动员的传记信息(他们在哪里长大,他们上过哪所高中,他们的名字),aplayer_to_team_history代表 aplayer上的 a 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

通过获取我们感兴趣的所有球员的player_to_team_history相关高中(高中的大学名单上的球员最多。accounts.AccountTypeId = 1accounts.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 中将所有内容拼接在一起会更好吗?

没有做 a select_by_sql,有什么地方我可以使用 Rails 让这更容易吗?

版本

Rails 3.2.1
Ruby 1.9.2 
4

2 回答 2

0

这可以使用 AREL 完成,但需要大量挖掘。但是我过去用来使子查询更容易的是使用squeel

“Squeel 让您可以使用更少的字符串和更多的 Ruby 来编写 ActiveRecord 查询,因为它使 ActiveRecord 下的 ARel 很棒更易于访问。”

于 2012-12-05T19:09:02.440 回答
0

虽然这并不能完全回答您的问题,但我建议您尝试这样做来解决您的问题。

获取现有的 SQL 查询并使用 SQL 模板 gem。

您可以尝试 基于Yesql的Yayql之类的东西,但任何文本或 SQL 模板引擎都可以。

于 2017-04-29T11:28:15.220 回答