2016-11-02 109 views
0
CName   | AddressLine 
------------------------------- 
John Smith  | 999 Somewhereelse 
Jane Doe  | 456 Evergreen Terrace 
John Black  | 999 Somewhereelse 
Joe Bloggs  | 1 Second Ave 

我想挑選唯一的AddressLine CName意味着我不想選擇「John Smith」和「John Black」,因爲他們有相同的地址。我怎麼做?如何獲得獨特的字段

+1

所以,你排除兩行或你需要其中之一?在那種情況下,這個約翰? – Horaciux

回答

0

使用EXISTS與分組和costraint它的輸出,其中一個ADDRES是having條款獨特:

select * 
from yourtable t1 
where exists (
    select addressline 
    from yourtable t2 
    where t1.addressline = t2.addressline 
    group by addressline 
    having count(*) = 1 
) 
+0

因爲EXISTS中的子查詢不相關,所以這不會給出期望的結果。所以如果保持原樣就會說任何地址線只有1個計數返回記錄。不,如果該行的地址線..... – Matt

+1

@Matt感謝您指出,我忘了。更正:-) –

2

對於所有非零地址可以組由addressline,並只選擇那些獨一無二的。

select * from t 
where addressline in (select addressline from t 
         where addressline is not null 
         group by addressline 
         having count(*) = 1) 
--or addressline is null 

select cname,addressline 
from (select t.*, count(*) over(partition by addressline) cnt 
     from t) x 
where cnt = 1 
1

您可以通過在子查詢中使用不帶組,在具有

select * from my_table 
where AddressLine not in (select AddressLine from my_table 
          group by AddressLine 
          where AddressLine is not null 
          having count(*) >1); 
+0

如果地址欄中有多個空值,這將不起作用。 –

+0

@vkp正確..答案已更新 – scaisEdge

0

幾乎相同的答案VKP爲COUNT(*),但我更喜歡它作爲公共表格表達。

;WITH cte AS ( 
    SELECT 
     * 
     ,COUNT(*) OVER (PARTITION BY AddressLine) as RecordsAtAddress 
    FROM 
     TableName 
) 

SELECT * 
FROM 
    cte 
WHERE 
    RecordsAtAddress = 1 

不過,我也想添加ROW_NUMBER窗函數來顯示你如何可以隨時選擇每個AddressLine的記錄。因此,在這種情況下,您將獲得1條重複記錄,而不是將它們排除在一起。

;WITH cte AS (
    SELECT * 
     ,ROW_NUMBER() OVER (PARTITION BY AddressLine ORDER BY CName) as RowNum 
    FROM 
     TableName 
) 

SELECT * 
FROM 
    cte 
WHERE 
    RowNum = 1 

是因人而異謹慎使用IN或NOT IN尤其是與自由形式的文字是這樣,因爲如果AddressLine可以爲NULL,你不會得到你所期望的!性能通常也不是很好。 NOT IN vs NOT EXISTS

對於EXISTS或NOT EXISTS回答你居然還要涉及您的子查詢這樣的事情,注意不是存在,則可能對於這樣的情況下有更好的表現:

SELECT * 
FROM 
    TableName t1 
WHERE 
    NOT EXISTS (SELECT 
       t2.AddressLine 
      FROM 
       TableName t2 
      WHERE 
       t1.AddressLine = t2.AddressLine 
      GROUP BY 
       t2.AddressLine 
      HAVING COUNT(*) > 1)