2017-09-28 8 views
0

私はSQLの初心者ですが、これは比較的基本的なクエリだと思いますが、動作させることができません。SQLコンプレックスフィルタ/結合問題

私は2つのテーブルを持っています。 1つは、グループのメンバーシップとそのグループのその他の詳細があります。両者のキーフィールドは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 

グループを変更したため、ジョーのための2つのエントリがあることに注意してください。

グループ情報は、次のようになります。

Group  FullName  Location Color 

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

私は任意の日に、チームの詳細と一緒に私の個々のグループメンバーシップを与える、クエリを実行したいです。だから、

、私は日付の実行時に、個々の人のために会員にMAX(EffectiveDate)の行を見つけたいと私は9/4にクエリを実行した場合は、私と思いキーGroup

にグループ情報テーブルを結合する左

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 

注2の違いその:私は9/13にクエリを実行した場合、私はこの取得したい

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 

:これを取得クエリ結果は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レコードの回答になります。

私が間違っていることを理解できません。ガイダンスをお願いします。

ありがとうございました。

+0

あなたのクエリは、最新の正確*メンバーシップの日付を*しているメンバーのみにレコードを制限していますメンバー。そのため、レコードが省略されています。 –

+0

使用しているdatbseで質問にタグを付けてください。 –

答えて

1

あなたは正しい軌道に乗っているが、間違った相関句使用:それはSQLキーワードなのでgroupは、SQLの列名の非常に悪い名前であることを

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' 
         ); 

注意を。

+0

あなたの答えをありがとう。グループはここのサンプルコードのサイトにあります。 – Windstorm1981

+0

サブクエリでなぜ 'where s1.Person = s.Person'が必要なのかを説明する(または私にソースを紹介する)ことができますか?私は直感的にそれを見ません。 – Windstorm1981

+1

@ Windstorm1981 's1.Person = s.Person'では、Joeの最新のEffectiveDateを取得します。条件がなければ、最後にグループに加わったメンバーの最新の有効期限を取得します。 – Eric

1

必要なのは、メンバシップデータをグループメンバ名と日付に再特徴付けし、それをサブクエリとして使用し、このメンバに参加させることです。あなたは基本的に "私に、与えられた興味のある日の前に各人の最大会員日付を教えてください"と言っています。注意:EffectiveDateフィールドが(DateTimeではなく)厳密に 'Date'である場合、誰かが同じ日に2回メンバーシップを変更した場合(理論的には1日以上の日付解決なし)には失敗する可能性があります。

が(この警告は非常に急いで一緒に投げられ、テストされていない)可能な代替としてこれを提案する:

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