2015-06-28 37 views

回答

0

對不起,這個回覆的冗長囉嗦。如果我的理解正確,您希望爲數據庫中的每個獨立地址創建一個郵件標籤,丈夫和妻子可以單獨或分別輸入。

你沒有提供太多的細節,所以我會舉兩個例子說明如何實現你想要的東西,一個基於能夠區分丈夫和妻子的性別,性別或稱呼欄目(例如先生或夫人)另一個基於簡單的最小和最大能夠獲得你需要的每個元素。

每個解決方案都需要使用SubQueries,這是一組包含在括號中的Select和From語句。由於它們返回一組數據,因此可將它們視爲表或查詢並用於外部From子句中。我們還將進行防禦性編碼,以確保我們不會被Null Propogation獲取,這意味着如果表達式中的任何一個或多個項目評估爲Null,則整個表達式將返回Null。

如果您需要一點Sql的進修,我會建議W3Schools Sql Tutorial

有關的例子而言跟隨,我用了一個家庭表中的MS Access,定義如下:

enter image description here

輸入一些測試數據,包括個人,夫婦和至少一個那裏是三個具有相同地址的記錄。

爲了獲得理想的結果,我們將使用Union All組合的表和子查詢的組合。我們將從最好的解決方案開始,這就是說,您可以通過主表中的某個列或通過外鍵將相關表中的男性和女性記錄區分開來。在上面的例子中,我們可以通過Sex或Salutation欄來區分男性和女性。我將使用性別欄來區分它們。

無論哪種情況,我們都會使用Group By子句來幫助我們獲得所需的結果。將Group By視爲一種內部排序,查詢在處理數據之前對其進行排序。 Group By的規則非常簡單,您不能引用Select語句中未包含在Group By子句中的任何列,除非它與僅返回一個值的Aggregate Function一起使用。所以在我們的例子中,我們沒有直接訪問FirstName或LastName列,但可以通過Min或Max函數引用它們。我們使用哪一個並不重要,因爲那個時候我們只有一個記錄要處理。

要審查,我們將需要三個結果集,一個具有唯一地址的單個記錄,一個具有唯一地址的兩個記錄,另一個具有其他所有地址。後一種情況並不是預期的,但確保在情況出現時至少對其進行處理。

第一種情況最簡單,如下面的代碼所示。從技術上講,我們不會真的需要First和Last名稱列上的別名,但它在測試時不會損害任何內容,並且會擊敗Expression1,Expression2等。

我們分組在Address1,Address2,City,State和ZipCode上。 Having子句將分組依據限制爲單行或具有多於兩行的唯一地址。

Select Max(FirstName) As FirstName2, Max(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
From Family 
Group By Address1, Address2, City, State, ZipCode 
Having Count(*) = 1 Or Count(*) > 2 

接下來,我們需要匹配丈夫和妻子的記錄。我們使用兩個基本相同的SubQueries,它們被定義爲tMen和tomen。 Inner Join的使用確保我們每個人都有一個匹配的男人和女人的行,並且Having條款的使用確保我們只處理兩條記錄。

有以下

  1. 訪問一對情侶在代碼感興趣的項目的要求列別名是不同於任何列名在GROUP BY引用
  2. 列可以在選擇
  3. 直接選擇
  4. 列中未引用的列通過在選擇中需要函數
  5. 在任何可能包含空數據的列上使用IIf和IsNull函數來保護我們免於空傳播

在SubQueries中,我們將函數別名爲FirstName2和LastName2。然後,在外部Select中,我們將FirstName2和LastName2別名爲FirstName和LastName。

Select (tMen.FirstName2 + ' and ' + tWomen.FirstName2) As FirstName, tMen.LastName2 As LastName, tMen.Address1, tMen.Address2, tMen.City, tMen.State, tMen.ZipCode, tMen.GroupCount 
From 
     (Select Min(FirstName) As FirstName2, Min(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
     From Family 
     Where Sex ='Male' 
     Group By Address1, Address2, City, State, ZipCode 
     Having Count(*) = 1) As tMen Inner Join 

     (Select Min(FirstName) As FirstName2, Min(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
     From Family 
     Where Sex ='Female' 
     Group By Address1, Address2, City, State, ZipCode 
     Having Count(*) = 1) As tWomen 

       On (tWomen.Address1 = tMen.Address1) And 
        (IIf(IsNull(tWomen.Address2), '', tWomen.Address2) = IIf(IsNull(tMen.Address2), '', tMen.Address2)) And 
        (tWomen.City = tMen.City) And 
        (tWomen.State = tMen.State) And 
        (tWomen.ZipCode = tMen.ZipCode) 

最後,我們把它放在一起的解決方法1. ORDER BY子句是最後的,涉及到整個結果集,而不是僅僅在聯盟所有的最後一個Select語句。此外,Union All連接的各種Select語句中的列的數量和類型必須匹配。列名來自第一個外部Select語句。

Select (tMen.FirstName2 + ' and ' + tWomen.FirstName2) As FirstName, tMen.LastName2 As LastName, tMen.Address1, tMen.Address2, tMen.City, tMen.State, tMen.ZipCode, tMen.GroupCount 
From 
     (Select Min(FirstName) As FirstName2, Min(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
     From Family 
     Where Sex ='Male' 
     Group By Address1, Address2, City, State, ZipCode 
     Having Count(*) = 1) As tMen Inner Join 

     (Select Min(FirstName) As FirstName2, Min(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
     From Family 
     Where Sex ='Female' 
     Group By Address1, Address2, City, State, ZipCode 
     Having Count(*) = 1) As tWomen 

       On (tWomen.Address1 = tMen.Address1) And 
        (IIf(IsNull(tWomen.Address2), '', tWomen.Address2) = IIf(IsNull(tMen.Address2), '', tMen.Address2)) And 
        (tWomen.City = tMen.City) And 
        (tWomen.State = tMen.State) And 
        (tWomen.ZipCode = tMen.ZipCode) 

Union All 

Select Max(FirstName) As FirstName2, Max(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
From Family 
Group By Address1, Address2, City, State, ZipCode 
Having Count(*) = 1 Or Count(*) > 2 

Order By LastName, FirstName, State, CIty, ZipCode 

由於這篇文章的篇幅,我會單獨發佈第二個解決方案。

0

繼續以前的解決方案,第二種方案是更普遍的,如果你有沒有可用的欄,讓您區分男性和女性定義的場景將被使用。它以類似於上面發佈的原始解決方案的方式使用SubQueries,但使用Min和Max來返回兩個唯一地址中的一個或另一個。這種解決方案不太可取,因爲它取決於丈夫和妻子的名字,所以丈夫或妻子首先或最後都不能。

該解決方案與上面發佈的第一個非常類似。因爲我們無法區分男女,因此性別='男'和性='女'的Where子句被刪除。相反,在每個子查詢的Group By子句下添加Having Count(*)= 2。然後我們使用FirstName和LastName上的Min和Max函數來獲取它們中的每一個。 Select語句中的Distinct語句確保我們只從每個SubQuery中獲得一個結果。

Select (tMin.FirstName2 + ' and ' + tMax.FirstName2) As FirstName, tMax.LastName2 As LastName, tMax.Address1, tMax.Address2, tMax.City, tMax.State, tMax.ZipCode, tMax.GroupCount 
From 
     (Select Distinct Max(FirstName) As FirstName2, Max(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
     From Family 
     Group By Address1, Address2, City, State, ZipCode 
     Having Count(*) = 2) As tMax Inner Join 

     (Select Distinct Min(FirstName) As FirstName2, Min(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
     From Family 
     Group By Address1, Address2, City, State, ZipCode 
     Having Count(*) = 2) As tMin 

       On (tMax.Address1 = tMin.Address1) And 
        (IIf(IsNull(tMax.Address2), '', tMax.Address2) = IIf(IsNull(tMin.Address2), '', tMin.Address2)) And 
        (tMax.City = tMin.City) And 
        (tMax.State = tMin.State) And 
        (tMax.ZipCode = tMin.ZipCode) 

Union All 

Select Max(FirstName) As FirstName2, Max(LastName) As LastName2, Address1, Address2, City, State, ZipCode, Count(*) As GroupCount 
From Family 
Group By Address1, Address2, City, State, ZipCode 
Having Count(*) = 1 Or Count(*) > 2 

Order By LastName, FirstName, State, CIty, ZipCode 
+0

非常感謝您的回覆,我會盡力解決您的問題,如果我找不到它,我會再次發帖。乾杯 – Davo

+0

只要記住標記爲答案,如果它有助於解決您的問題。 – j2associates

相關問題