ldr*_*drg 5 sql postgresql join aggregate-functions
这是我的架构和问题的基本内容:http://sqlfiddle.com/#!1/72ec9/4/0
请注意,句号表可以指一个可变的时间范围 - 可能是整个赛季,可能是几场比赛或一场比赛.对于给定的团队和年份,所有期间行代表独有的时间范围.
我写了一个查询,它连接表并使用GROUP BY periods.year来汇总一个季节的分数(参见sqlfiddle).但是,如果一名教练在同一年有两个职位,GROUP BY将计算两次同一时期的排名.当教练担任两个职位但仍总结一年由多个时期组成的时期时,我怎么能抛弃重复数据呢?如果有更好的方法来制作模式,如果你向我指出,我也会很感激.
将潜在的问题(加入与多个匹配多个表)在此紧密相关的答案解释:
要修复,我首先简化了您的查询:
select pe.year
, sum(pe.wins) AS wins
, sum(pe.losses) AS losses
, sum(pe.ties) AS ties
, array_agg(po.id) AS position_id
, array_agg(po.name) AS position_names
from periods_positions_coaches_linking pp
join positions po ON po.id = pp.position
join periods pe ON pe.id = pp.period
where pp.coach = 1
group by pe.year
order by pe.year;
Run Code Online (Sandbox Code Playgroud)
产生与原始相同,不正确的结果,但更简单/更快/更容易阅读.
coach只要不使用SELECT列表中的列,就没有必要加入表.我完全删除了它并WHERE用where pp.coach = 1.
你不需要COALESCE.NULL在聚合函数中忽略值sum().无需替代0.
使用表别名可以更容易阅读.
接下来,我解决了你的问题:
SELECT *
FROM (
SELECT pe.year
, array_agg(DISTINCT po.id) AS position_id
, array_agg(DISTINCT po.name) AS position_names
FROM periods_positions_coaches_linking pp
JOIN positions po ON po.id = pp.position
JOIN periods pe ON pe.id = pp.period
WHERE pp.coach = 1
GROUP BY pe.year
) po
LEFT JOIN (
SELECT pe.year
, sum(pe.wins) AS wins
, sum(pe.losses) AS losses
, sum(pe.ties) AS ties
FROM (
SELECT period
FROM periods_positions_coaches_linking
WHERE coach = 1
GROUP BY period
) pp
JOIN periods pe ON pe.id = pp.period
GROUP BY pe.year
) pe USING (year)
ORDER BY year;
Run Code Online (Sandbox Code Playgroud)
在加入之前单独汇总头寸和期间.
在第一个子查询列表中,只需使用一次即可定位一次DISTINCT.
在第二个子查询中
GROUP BY period,因为教练每个时期可以有多个职位.JOIN以期数据后说,然后汇总得到的款项.