所以,假设我有一个哈希/关系表,用于连接用户,用户可以加入的团队,以及团队参与的挑战(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 = ___
如果用户错误地加入了多个团队,他将在teams_users_challenges
中有多个条目,这实际上会复制检索到的数据。因此,如果一个用户在同一个挑战的3个不同的团队中,他将在teams_users_challenges
中有3个条目,这将使他们的平均value
乘以3,这要归功于LEFT JOIN
它会自动接收所有记录,而不仅仅是一个记录。
我已尝试使用GROUP BY
,但这似乎并未将数据仅限制为teams_users_challenges
中的一个实例。有没有人想过如何限制查询只能在teams_users_challenges
内收录一条记录?
ADDENDUM: teams_users_challenges
中的列为team_id
,user_id
和challenge_id
。
答案 0 :(得分:1)
如果这是一个新的空表,您可以表达您的“业务规则”,即用户每次挑战只能加入一个团队作为SQL中的unique
约束:
alter table teams_users_challenges
add constraint oneUserPerTeamPerChallenge
unique (
user_id
, team_id
, challenge_id
);
如果您无法更改表格,则需要按用户和团队进行分组,并从查询结果中的每个组中挑选一个挑战。也许只选择最新的挑战。
答案 1 :(得分: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 = ___