2017-09-28 65 views
0

我是SQL新手,我認爲這是一個相對基本的查詢,但似乎無法使其工作。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 

注意,有喬的兩個條目,因爲他改變組。

GroupInformation是這樣的:

Group  FullName  Location Color 

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

我想運行一個查詢,在任何一天,都會給我個人的組成員與團隊詳細信息。

所以,我想找到與MAX(EffectiveDate)行中的成員身份在指定日期運行中每個個體的人,離開加入GroupInformation表上的關鍵Group

如果我跑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條記錄的答案。

無法弄清楚我做錯了什麼。請指導。

謝謝。

+0

您的查詢限制記錄僅誰也正是*的成員*最新的成員日期會員。這就是爲什麼記錄被省略。 –

+0

用你正在使用的datbse標記你的問題。 –

回答

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關鍵字。

+0

感謝您的回答。 Group就在我的示例代碼中。 – Windstorm1981

+0

你能解釋一下(或者把我引用到一個源代碼)爲什麼我需要'where s1.Person = s.Person'在子查詢中嗎?我不直觀地看到它。 – Windstorm1981

+1

@ Windstorm1981's1.Person = s.Person'確保您獲得Joe的最新EffectiveDate。沒有條件,您將獲得最後加入該組的成員的最新EffectiveDate。 – Eric

1

您需要的是將成員資格數據重新定義爲組成員名稱以及日期,然後將其用作子查詢並以此靜態加入。你基本上是說「在給定的利息日之前給我每個人的最大會員資格日期。」警告:如果EffectiveDate字段嚴格爲'日期'(而不是日期時間),那麼如果有人在同一天更改了兩次會員資格(在日期之後沒有日期分辨率),理論上它仍然會失敗。

推薦這個作爲一個可能的替代(警告這是非常匆忙拼湊而成,而不是測試):

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