我们有关于 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 = 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 中将所有内容拼接在一起会更好吗?
没有做 a select_by_sql
,有什么地方我可以使用 Rails 让这更容易吗?
版本
Rails 3.2.1
Ruby 1.9.2