SQL Server消除了具有“重复”数据的行

时间:2013-01-05 16:44:57

标签: sql sql-server

我的数据格式如下:

DATE                 DATA1                 DATA2
-------------------------------------------------
20121010             ABC                   DEF
20121010             DEF                   ABC
20121010             HIJ                   KLM
20121010             KLM                   HIJ
20121212             ABC                   DEF
20121212             DEF                   ABC
20121212             HIJ                   KLM
20121212             KLM                   HIJ

我想要做的是选择第1行和第3行。我不关心第2行和第4行,因为它们在我眼中基本上是“重复”。

似乎很简单,但我只是想把查询放在一起来完成这个。

5 个答案:

答案 0 :(得分:1)

假设您使用的是2005或更高版本,可以使用row_number()函数:

select date, data1, data2
from (select t.*,
             row_number() over (partition by date order by date) as seqnum
      from t
     ) t
where seqnum = 1

表达式order by date应在任何支持row_number的数据库中生成任意顺序。在SQL Server中,您还可以使用order by (select NULL)

或者,我意识到你的问题可能是关于消除重复,无论顺序如何。为此,你可以这样做:

select distinct date, minData, maxData
from (select t.date,
             (case when data1 > data2 then data1 else data2 end) as minData,
             (case when data1 > data2 then data2 else data1 end) as maxData
      from t
     ) t

但是,当只出现一行时,这可能会重新排列这两个值。

维护列的原始排序和消除额外行的更复杂的解决方案结合了两种方法:

select date, data1, data2
from (select t.*,
             row_number() over (partition by date order by minData, maxData) as seqnum
      from (select t.*
                   (case when data1 > data2 then data1 else data2 end) as minData,
                   (case when data1 > data2 then data2 else data1 end) as maxData
            from t
           ) t
     ) t
where seqnum = 1

答案 1 :(得分:1)

SELECT Date,  Data1, Data2
FROM tableX
WHERE Data1 <= Data2

UNION 

SELECT Date,  Data2, Data1
FROM tableX
WHERE Data2 < Data1 ;

答案 2 :(得分:0)

我喜欢这样:但我相信如果您使用前SQL-Server 2008R2

,它将无效
;WITH myCTE
        AS
        (
        SELECT 
            [Rw] = ROW_NUMBER() OVER (ORDER BY [Date]),
            [Date],
            [DATA1],
            [DATA2]
        FROM #data
        )
SELECT *
FROM myCTE x    
WHERE NOT EXISTS
            (
            SELECT 1
            FROM myCTE y
            WHERE
                x.DATA1 = y.DATA2 AND
                x.Rw > y.Rw AND
                x.Date = y.Date
            )

以下是SQL Fiddle

的实时插图

答案 3 :(得分:0)

你可以试试这个:

SQL DEMO HERE

;WITH CTE AS
(
  SELECT date, data1, data2, 
  CASE WHEN DATA2 > DATA1 THEN data1 + data2 
  ELSE data2 + data1 END d
  FROM T
),CTE2 AS 
(
  SELECT *,
  ROW_NUMBER() OVER (PARTITION BY DATE, d 
                     ORDER BY data1) rn
  FROM CTE
)
SELECT date, data1, data2 FROM CTE2 WHERE rn = 1

答案 4 :(得分:0)

 ;WITH cte AS
 (
  SELECT DATE, DATA1, DATA2, ROW_NUMBER() OVER(ORDER BY DATE, DATA1) AS Id
  FROM dbo.test70 t
  )
  SELECT c.DATE, c.DATA1, c.DATA2
  FROM cte c LEFT JOIN cte ct ON c.Id = ct.Id + 1 AND c.DATA1 = ct.DATA2 
  WHERE ct.DATE IS NULL

SQLFiddle上的演示