2016-09-16 19 views
0

私は次のようにいくつかの冗長データを持つSQLテーブルを持っています。私はそれが基本的にSQL Serverテーブルから重複する行を削除する

ColumnA(varchar) | ColumnB(varchar) 
---------------- | --------------- 
name3   | name4 
name2   | name1 
name5   | name6 

または

ColumnA(varchar) | ColumnB(varchar) 
---------------- | --------------- 
name1   | name2 
name3   | name4 
name5   | name6 

その結果、私を与えるような、このテーブルは異なるデータ/行を選択する必要があります(SQL Server 2012の)

ColumnA(varchar) | ColumnB(varchar) 
---------------- | --------------- 
name1   | name2 
name3   | name4 
name2   | name1 
name5   | name6 

、NAME1 & name2は、name2 & name1(存在する列の順序にかかわらず)として存在する場合、一意であるとみなされるべきです。

異なる列で等しい文字列に基づいて行をどのようにフィルタリングできないかわかりません。

誰かがこれを手伝ってくれますか?

答えて

1

あなたはこのようなロジックを使用してデータを削除することができます。

delete from t 
    where t.columnB > t.columnA and 
      exists (select 1 
        from t t2 
        where t2.columnA = t.columnB and t2.columnB = t.columnA 
       ); 

あなたが実際にレコードを削除したいのですが、単純に重複せずに結果セットを返すようにしたくない場合は、類似したクエリを使用することができます:

select t.columnA, t.columnB 
from t 
where t.columnA < t.columnB 
union all 
select t.columnA, t.columnB 
from t 
where t.columnA > t.columnB and 
     not exists (select 1 
        from t t2 
        where t2.columnA = t.columnB and t2.columnB = t.columnA 
       ); 
+0

したがって、テストデータが実際にname1 name2とname2 name1を複製する場合、すべての重複を削除すると1つのニュアンスが生じます。両方ともデータセットで2回表現されると、これらのステートメントはそれらの重複の1つのセットを削除しません。 – Matt

+0

@Matt。 。 。 OPの目的は、2つの列の値が逆の順序で定義されている場合、「重複」を削除することです。*「基本的に、name1とname2はname2とname1として存在する場合は一意であると考えるべきです(それらが存在する列の順序に関係なく)」* –

1
with TabX as(
select 'name1' as ColumnA, 'name2' as ColumnB 
union all 
select 'name3' as ColumnA, 'name4' as ColumnB 
union all 
select 'name2' as ColumnA, 'name1' as ColumnB 
union all 
select 'name5' as ColumnA, 'name6' as ColumnB 
) 

select min(ColumnA) as ColumnA,max(ColumnB) as ColumnB 
    from tabX 
group by case when ColumnA > ColumnB then ColumnA+ColumnB else ColumnB+ColumnA end 
+0

グレートアンサーマイク! – Matt

0
;WITH cte AS (
    SELECT * 
     ,ROW_NUMBER() OVER (PARTITION BY 
      CASE WHEN ColumnA < ColumnB THEN ColumnA + ColumnB ELSE ColumnB + ColumnA END 
      ORDER BY (SELECT 0)) as RowNumber 
    FROM 
     @Table 
) 

DELETE FROM cte 
WHERE 
    RowNumber > 1 

あなたが選ぶのではなく

0123に変更し、削除したい場合
SELECT * FROM cte WHERE RowNumber = 1 

またはあなたはまた、@マイクと同様の方法を使用して、ちょうどユニークな組み合わせを得るためにDISTINCTとストレートcase式を行うことができます。ここでは

SELECT DISTINCT 
    CASE WHEN ColumnA < ColumnB THEN ColumnA ELSE ColumnB END as ColumnA 
    ,CASE WHEN ColumnA < ColumnB THEN ColumnB ELSE ColumnA END as ColumnB 
FROM 
    @Table 

をいくつかのテストデータです:

DECLARE @Table AS TABLE (ColumnA VARCHAR(10),ColumnB VARCHAR(10)) 
INSERT INTO @Table VALUES 
('name1','name2') 
,('name3','name4') 
,('name2','name1') 
,('name2','name1') 
,('name5','name6') 
,('name1','name2') 
0

ここで(dupesのためのあなたの基準あたり)行の完全デだまさセットを取得するための簡単な方法です:

select t.columnA, t.columnB 
from (
    select t.columnA, t.columnB, 
    row_number() over (
     partition by 
      case when t.columnA >= t.columnB then t.columnA + t.columnB 
      else t.columnB + t.columnA end 
     order by t.columnA) as rseq 
     /* order of "dupes" decided above, only first one gets rseq = 1 */ 
    from t 
) t 
where t.rseq = 1 
関連する問題