1

因此,假设我有一个哈希/关系表,它连接用户、用户可以加入的团队以及团队参与的挑战 ( teams_users_challenges),以及一个存储给定挑战中所有用户输入数据的表 ( entry_data)。我想获得挑战中每个用户的平均分数(给定一周内每天的平均值)。但是,用户可能会以某种方式错误地加入多个团队(这不应该发生,但有时会发生)。下面是获取特定用户分数的 SQL 查询:

SELECT tuc.user_id, SUM(ed.data_value) / 7 as value
FROM teams_users_challenges tuc
LEFT JOIN entry_data ed ON (
    tuc.user_id = ed.user_id AND
    ed.entry_date BETWEEN '2013-09-16' AND '2013-09-22'
)
WHERE tuc.challenge_id = ___
AND tuc.user_id = ___

如果用户错误地加入了多个团队,(s)他将有多个条目teams_users_challenges,这实际上会复制检索到的数据。因此,如果用户在 3 个不同的团队中进行相同的挑战,(s)他将有 3 个条目teams_users_challenges,这将使他们的平均值乘以value3,这要归功于LEFT JOIN自动接收所有记录,而不仅仅是一个。

我试过使用GROUP BY,但这似乎并没有将数据限制在teams_users_challenges. 是否有人对我如何将查询限制为仅包含其中的一条记录有任何想法teams_users_challenges

附录:内的列teams_users_challengesteam_iduser_idchallenge_id

4

2 回答 2

1

如果这是一个新的空表,您可以表达您的“业务规则”,即用户每次挑战只能加入一个团队作为uniqueSQL 中的约束:

alter table teams_users_challenges
add constraint oneUserPerTeamPerChallenge
unique (
  user_id
, team_id
, challenge_id
);

如果您无法更改表格,则需要按用户和团队分组,并从查询结果中的每个组中选择一个挑战。也许只选择最新的挑战。

于 2013-09-27T16:47:47.940 回答
1

我无法对其进行测试,但如果您无法按照 Yawar 的建议清理数据,请尝试:

SELECT tuc.user_id, SUM(ed.data_value) / 7 as value
FROM entry_data ed
LEFT JOIN
(
select tuc.user_id, tuc.challenge_id from teams_users_challenges tuc group by tuc.user_id, tuc.challenge_id
) AS SINGLE_TEAM
 ON SINGLE_TEAM.user_id = ed.user_id AND
    ed.entry_date BETWEEN '2013-09-16' AND '2013-09-22'
WHERE tuc.challenge_id = ___
AND tuc.user_id = ___
于 2013-09-27T17:05:30.200 回答