2016-12-21 31 views
0

我有一個簡單的查詢,返回給定客戶的電話號碼列表。用戶可以通過輸入他們地址的任何部分來搜索特定的客戶。客戶可以有多個電話號碼和地址。如何過濾掉由SQL中的JOIN引起的重複記錄?

這裏是我的查詢的示例:

SELECT 
ROW_NUMBER() OVER(PARTITION BY Customer.CustomerNumber, ORDER BY PhoneNumber.PhoneNumber) RowNumber, 
Customer.CustomerNumber, 
PhoneNumber.PhoneNumber 
FROM Customer 
JOIN PhoneNumber ON PhoneNumber.CustomerId = Customer.Id 
JOIN CustomerAddress on CustomerAddress.CustomerId = Customer.Id 

下面是這個查詢是生產時,我有一個具有兩個電話號碼和兩個地址的客戶:

RowNumber  CustomerNumber  PhoneNumber 
1    1     111-111-1111 
2    1     222-222-2222 
3    1     111-111-1111 
4    1     222-222-2222 

我想要的結果將沿着這些線:

RowNumber  CustomerNumber  PhoneNumber 
1    1     111-111-1111 
2    1     222-222-2222 

我只能產生以上所需的結果當我刪除地址表上的連接時。

用戶應該能夠通過輸入在地址的任何部分來查找客戶(例如:我想說明,在鳳凰城地址的任何用戶)。雖然它不顯示在結果中,但仍應可過濾。

我覺得我能夠做這樣的事:

SELECT *, ROW_NUMBER() OVER(PARTITION BY Test.CustomerNumber ORDER BY Test.PhoneNumber) RowNumber 
FROM 
(
    SELECT 
    DISTINCT 
    CustomerNumber, 
    PhoneNumber.PhoneNumber 
    FROM Customer 
    JOIN PhoneNumber ON PhoneNumber.CustomerId = Customer.Id 
    JOIN CustomerAddress ON CustomerAddress.CustomerId = Customer.Id 
) Test 
+0

嘗試添加字段從地址到結果,看看有什麼重複。數據庫可能允許每個客戶有多個地址。 – SMM

+5

然後刪除加入到地址表。無論如何,你並沒有使用它。 – RBarryYoung

+1

任何你不使用DISTINCT的原因? – SteveJ

回答

2

你不是從CustomerAddress表中選擇任何列,所以加入該表只有抑制效果,爲客戶提供無地址的影響併爲具有多個地址的人員複製結果。

如果你不希望其中的任意一種的效果,然後不加入CustomerAddress。如果你只想要前者,那麼你肯定會在不同的方法更好,如

SELECT 
    ROW_NUMBER() OVER(PARTITION BY Customer.CustomerNumber, 
    ORDER BY PhoneNumber.PhoneNumber) RowNumber, 
    Customer.CustomerNumber, 
    PhoneNumber.PhoneNumber 
FROM 
    Customer 
    JOIN PhoneNumber ON PhoneNumber.CustomerId = Customer.Id 
WHERE 
    Customer.Id IN (SELECT CustomerId from CustomerAddress) 

假定該Customer.Id是主鍵,這應該產生只有當給定客戶重複的電話號碼被記錄重複在PhoneNumber表中。

+0

我需要它作爲搜索特定客戶的能力。執行搜索時創建where子句。因此,客戶可以搜索亞利桑那州鳳凰城的任何客戶。所以我需要訪問這張表。 – ferensilver

+0

@ferensilver您可以在子查詢中的WHERE子句中添加地址標準。 –

2

刪除加入地址可能會影響用戶按地址進行搜索的能力。如果是這樣的問題,更改查詢使用exists

SELECT ROW_NUMBER() OVER (PARTITION BY c.CustomerNumber ORDER BY pn.PhoneNumber) as RowNumber, 
     c.CustomerNumber, 
     pn.PhoneNumber 
FROM Customer c JOIN 
    PhoneNumber pn 
    ON pn.CustomerId = c.Id 
WHERE EXISTS (SELECT 1 
       FROM CustomerAddress ca 
       WHERE ca.CustomerId = c.Id AND 
        ca.address like '%@ADDRESS%' -- this is just an example of searching logic 
      ); 
+0

基於修改的問題,這似乎是一個很好的答案。如果重複地址是因爲數據庫將結算地址和送貨地址存儲在同一個表中,則可能需要將其添加到過濾器中。 – SMM

0

改變你的窗函數由客戶和電話號碼在子查詢分區。我一直使用這個來過濾僞裝。只需將分區設置爲您的唯一密鑰即可。

Select * from ( SELECT ROW_NUMBER() OVER(PARTITION BY Customer.CustomerNumber, PhoneNumber PhoneNumber, ORDER BY PhoneNumber.PhoneNumber) RowNumber, Customer.CustomerNumber, PhoneNumber.PhoneNumber FROM Customer JOIN PhoneNumber ON PhoneNumber.CustomerId = Customer.Id JOIN CustomerAddress on CustomerAddress.CustomerId = Customer.Id) Where RowNumber = 1