【问题标题】:SQL Complex Filter/Join IssueSQL 复杂过滤器/连接问题
【发布时间】:2017-09-28 13:44:17
【问题描述】:

我是 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

我想在任何一天运行一个查询,该查询将为我提供个人的组成员身份以及团队详细信息。

所以,我想在运行日期为每个人在 Membership 中找到带有 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 的比赛让他在 8 月 5 日加入 A 组,而 9/13 的比赛让他在 9/10 加入的 B 组。

我的查询代码如下:

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 条记录的答案。

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

谢谢。

【问题讨论】:

  • 您的查询将记录限制为仅具有确切最新成员的成员资格日期的成员。这就是记录被省略的原因。
  • 用您正在使用的数据标记您的问题。

标签: sql sql-server join


【解决方案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 关键字。

【讨论】:

  • 感谢您的回答。组只是我在网站上的示例代码。
  • 您能否解释(或将我引荐给来源)为什么我在子查询中需要where s1.Person = s.Person?我不直观地看到它。
  • @Windstorm1981 s1.Person = s.Person 确保您获得 Joe 的最新 EffectiveDate。如果没有条件,您将获得最后加入群组的成员的最新 EffectiveDate。
【解决方案2】:

您需要将成员资格数据重新定义为对成员姓名和日期进行分组,然后将其用作子查询并以这种方式加入它。您基本上是在说“在给定的兴趣日期之前给我每个人的最大会员日期。”警告:如果 EffectiveDate 字段是严格的“日期”(而不是 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-25
    • 2022-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多