选择相关表中第一行和最后一行的总和

时间:2019-01-10 20:04:09

标签: sql sql-server

在我的表格中,我有以下三个表格:

团队:

Id GUID UNIQUE PRIMARY
Name NVARCHAR

参与者:

Id GUID UNIQUE PRIMARY
FirstName NVARCHAR
[....]
TeamId GUID

ParticipantData:

Id GUID UNIQUE PRIMARY
Weight FLOAT
Date DATETIME
ParticipantId GUID
TeamId GUID

我需要的是一个SQL查询,该查询提供了Teams AND的所有列:

  • 团队中参与者(TeamId)的ParticipantData中的第一个(按日期排序)条目的总和

  • 团队中参与者(TeamId)的ParticipantData中最后(按日期排序)条目的总和

说明:

我有很多参与者(团队成员)以一定的时间间隔(体重+日期)报告体重。我要完成的工作是计算所有团队成员的体重减轻。

  

在2019-01-03参与者1报告了体重78

     

在2019-01-06参与者1报告了体重75

     

在2019-01-04上,参与者2报告了体重86

     

在2019-01-07上,参与者2报告了体重83

     

我需要查询以获取SumOfFirstWeights(78 + 86)= 164

     

我需要查询以获取SumOfLastWeights(75 + 83)= 158

这使我的体重减轻了6。

我尝试了以下多种组合:

Select *, 
(SELECT TOP (1) Sum(Weight) 
 FROM ParticipantData WHERE (TeamId = Teams.Id) 
 GROUP BY ParticipantId
)
ORDER BY Date As SumOfFirstWeights 
From Teams

2 个答案:

答案 0 :(得分:0)

您的问题是每个组中最大/最小的问题,此外,您需要这些值的总和。

select t.id, t.name, sum(t1.weight), sum(t2.weight)
from teams t
left join
(
    select pd.teamid, pd.participantid, pd.weight
    from ParticipantData pd
    join 
    (
        select teamid, participantid, min(date) min_date
        from ParticipantData 
        group by teamid, participantid
    ) t on pd.teamid = t.teamid and 
           pd.participantid = t.participantid and
           pd.date = t.min_date
) t1 on t.id = t1.teamid
left join 
(
    select pd.teamid, pd.participantid, pd.weight
    from ParticipantData pd
    join 
    (
        select teamid, participantid, max(date) max_date
        from ParticipantData 
        group by teamid, participantid
    ) t on pd.teamid = t.teamid and 
           pd.participantid = t.participantid and
           pd.date = t.max_date
) t2 on t1.teamid = t2.teamid and
        t1.participantid = t2.participantid
group by t.id, t.name

答案 1 :(得分:0)

您要查找每个团队的第一行和最后一行。您可以为此使用分析功能。我正在使用ROW_NUMBER,即使参与者在同一天有两个条目,它也只能给我一个记录。

with pd as
(
  select
    participantid,
    weight,
    row_number() over (partition by participantid order by date) as one_is_first,
    row_number() over (partition by participantid order by date desc) as one_is_last
  from participantdata
)
, team_weights as
(
  select
    p.teamid,
    sum(case when pd.one_is_first = 1 then weight end) as first_weight,
    sum(case when pd.one_is_last = 1 then weight end) as last_weight,
    sum(case when pd.one_is_last = 1 then weight end) -
    sum(case when pd.one_is_first = 1 then weight end) as difference
  from pd
  join participant p on p.id = pd.participantid
  where (pd.one_is_first = 1 or pd.one_is_last = 1)
  group by p.teamid
)
select *
from teams
join team_weights on where team_weights.team_id = teams.id
order by teams.id;
相关问题