我们有关于NCAA运动员的信息以及这些运动员上高中的地方。我们希望按照参加高中的NCAA运动员数量对高中进行排名。
我们有players
,teams
,team_histories
,accounts
和player_to_team_histories
。 account
表示学校(姓名,地点,类型(大学,高中)),team
描述account
(男子足球,女子排球)的特定球队,team_history
{1}}代表特定team
(2012年男子足球队)的一年,player
代表运动员的传记信息(他们长大的地方,他们就读的高中,他们的名字) ),player_to_team_history
表示player
上的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
分组然后按每个小组的计数排序,从而为我们提供一个排序列表,列出哪些高中的大学球员名单最多。
RANKING
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