2014-03-31 101 views
2

我有一個表是這樣的:的SQL Server刪除重複的縮寫

acronym | word 
FCN  | FCN 
FCN  | Fourth Corner Neurosurgical Associates 
FHS  | FHS 
HW  | HW 

正如你看到的,一些縮略語具有匹配的詞,有些則沒有。我想保留具有匹配詞的首字母縮略詞。對於沒有匹配詞的首字母縮寫詞,我想保留縮寫本身。我期望結果表看起來像:

acronym | word 
FCN  | Fourth Corner Neurosurgical Associates 
FHS  | FHS 
HW  | HW 

我想不出一種方法來完成這一點呢。通過「縮寫」,然後選擇「文字」可能分組,但什麼算法可以決定刪除「FCN」或「第四角神經外科協會」

回答

3

假設不能有任何「壞」字:

DELETE myTable 
    FROM myTable del 
WHERE [acronym] = [word] 
    AND EXISTS (SELECT * 
        FROM myTable lw -- Longer Word 
       WHERE lw.[acronym] = del.[acronym] 
        AND Len(lw.[word]) > Len(lw.[acronym])) 

還是你想避免刪除SQL|SQL當有一個'壞'其他(較長)的記錄,例如讀取。 SQL|Strange Things Happen

重讀這個問題我現在懷疑你是否真的想要DELETE這些記錄,或者只是想從中刪除記錄的記錄中的SELECT。在後一種情況下,你必須使用(包括mellamokb的建議)

SELECT [acronym], [word] 
    FROM myTable mt 
WHERE [acronym] <> [word] 
    OR NOT EXISTS (SELECT * 
         FROM myTable lw 
        WHERE lw.[acronym] = mt.[acronym] 
         AND lw.[word] <> lw.[acronym]) 
+4

從技術上講,Len(lw。[word])> Len(lw。[acronym])不是要求的,儘管它是常識。爲什麼不使用'AND [word] <> [acronym]'? – mellamokb

+0

我想這也會起作用......我只是假設'word'是'acronym'的長版本,並沒有深思。爲了'不同'也許也可以。我最初的想法是檢查'word'是否符合實際的'首字母縮略詞',所以'Len()'已經是一個重要的簡化了。=) – deroby

+0

@deroby - 如果你只想選擇而不刪除,這樣可以嗎?我不能修改這個查詢做了刪除'選擇a1.acronym,a2.word 從 ( 選擇的縮寫,COUNT(縮寫)爲CNT 從縮略詞 組由縮寫 )爲A1 左連接縮略詞A2 on a1.acronym = a2.acronym where(cnt> 1 and a1.acronym = word) ' –

0

根據您的資料,您可以用鮮明的組合和Case語句

select distinct acronym, 
(case acronym when word then word else acronym end) as Abbr 
from acronyms 
0

試試這個:

create table #t (acronym varchar(100), word varchar(100)); 
go 
insert #t values 
('FCN', 'FCN'), 
('FCN', 'Fourth Corner Neurosurgical Associates'), 
('FHS', 'FHS'), 
('HW', 'HW'); 
go 

;with x as (
    select *, 
    row_number() over(partition by acronym order by case when acronym=word then 1 else 0 end) as rn 
    from #t 
) 
delete x where rn <> 1;