SQL复杂过滤/加入问题

时间:2017-09-28 13:44:18

标签: sql sql-server join

我是SQL的新手,我认为这是一个相对基本的查询,但我似乎无法让它工作。

我有两张桌子。一个有团体成员资格,另一个有关该团体的详细信息。两者之间的关键字段是Group

会员资格如此。

Person    EffectiveDate    Group

Mary        8/10/2017        A
Joe         8/05/2017        A
Peter       9/01/2017        B
Mike        9/2/2017         B
Alice       9/2/2017         B
Joe         9/10/2017        B
Pam         9/3/2017         C

请注意,Joe有两个条目,因为他 已更改 组。

GroupInformation看起来像这样:

Group     FullName     Location    Color

A          Panthers     New York    Blue
B          Steelers     London      Orange
C          Archers      Moscow      Yellow

我想运行一个查询,在任何一天,它会给我个人的团队成员资格以及团队详细信息。

所以,我想在日期运行中为每个人找到会员中MAX(EffectiveDate)的行,然后在关键Group上加入GroupInformation表

如果我在9/4上运行查询,我会得到这个:

Person    EffectiveDate   Group   FullName    Location   Color

Mary        8/10/2017        A     Panthers     New York    Blue
Joe         8/05/2017        A     Panthers     New York    Blue
Peter       9/01/2017        B     Steelers     London      Orange
Mike        9/2/2017         B     Steelers     London      Orange
Alice       9/2/2017         B     Steelers     London      Orange
Pam         9/3/2017         C     Archers      Moscow      Yellow

如果我在9月13日运行查询,我会得到这个:

Person    EffectiveDate   Group   FullName    Location   Color

Mary        8/10/2017        A     Panthers     New York    Blue
Peter       9/01/2017        B     Steelers     London      Orange
Mike        9/2/2017         B     Steelers     London      Orange
Alice       9/2/2017         B     Steelers     London      Orange
Joe         9/10/2017        B     Steelers     London      Orange
Pam         9/3/2017         C     Archers      Moscow      Yellow

请注意,两个查询结果之间的差异是Joe。 9/4比赛让他在A组加入8/5,9/13比赛将他带到B组,并于9月10日加入。

我的查询代码如下:

Select s.Person,
       s.Group,
       s.EffectiveDate,
       g.FullName,
       g.Location,
       g.Color

From   Membership s
Join   GroupInformation g
  on   s.Group = g.Group
  and  s.EffectiveDate = (
       Select Max(s1.EffectiveDate)
       From Membership s1
       where s1.Group = g.Group
       and s1.EffectiveDate <= '2017-09-14')

然而,当我运行此代码时,我在实际数据中发现它省略了记录。因此,如果我在成员资格中有150条记录,则生成的查询连接和子查询操作将产生可能有80条记录的答案。

无法弄清楚我做错了什么。请指导。

感谢。

2 个答案:

答案 0 :(得分:1)

你走在正确的轨道上,但使用错误的相关条款:

Select s.Person, s.Group, s.EffectiveDate, g.FullName, g.Location, g.Color
From Membership s Join
     GroupInformation g
     on s.Group = g.Group
WHERE s.EffectiveDate = (Select Max(s1.EffectiveDate)
                         From Membership s1
                         where s1.Person = s.Person and
                               s1.EffectiveDate <= '2017-09-14'
                        );

请注意,group是SQL中列名的一个非常差的名称,因为它是一个SQL关键字。

答案 1 :(得分:1)

您需要的是将成员资格数据重新定义为组成员名称和日期,然后将其用作子查询并以此方式加入其中。您基本上是在说明&#34;在给定的感兴趣日期之前给我每个人的最大会员日期。&#34;警告:如果EffectiveDate字段是严格的&#39;日期&#39; (而不是DateTime),如果有人在同一天更改了两次会员资格(当天没有日期解决方案),理论上它仍然会失败。

建议将此作为一种可能的替代方案(警告这是非常匆匆抛在一起而未经过测试):

select s.person, s.group, s.EffectiveDate, g.FullName,g.location, g.color
  from (select m.person,m.group, max(m.effectivedate) effectivedate
          from Membership m
         where m.EffectiveDate <= '2017-09-14'
         group by m.person,m.group) s
  join GroupInformation g
    on s.group=g.group