SQL Server分区通过提供重复记录

时间:2016-11-29 16:17:11

标签: sql sql-server tsql

我有以下表格:

Date     | ID | firstname 
---------+----+------------
20161128 | 1  | Adam      
20161128 | 2  | Steve     
20161128 | 2  | Steve     
20161128 | 3  | Aaron     
20161129 | 1  | Adam      
20161129 | 2  | Steve     
20161129 | 2  | Steve     
20161129 | 3  | Aaron     

我想通过ID获取某个特定日期的第一行。

所以我拥有的是:

SELECT *    
FROM tableA   
WHERE Date = 20161128
然而,

这给出了所有记录。所以我使用了分区而不是函数:

SELECT 
    *,
    row_number() over(partition by ID order by Date desc) 
FROM tableA 
WHERE Date = 20161128

在这种情况下,我得到以下结果:

Date     | ID | firstname | rownum
---------+----+-----------+-------
20161129 | 1  | Adam      | 1
20161129 | 1  | Adam      | 2
20161129 | 2  | Steve     | 1
20161129 | 2  | Steve     | 2
20161129 | 2  | Steve     | 3
20161129 | 2  | Steve     | 4
20161129 | 2  | Steve     | 5
20161129 | 2  | Steve     | 6
20161129 | 3  | Aaron     | 1
20161129 | 3  | Aaron     | 2

如您所见,大多数ID出现2次。 (ID 2甚至出现6次)。在其他情况下,我看到一条记录出现了10次,即使它只有一条记录,如果我使用第一个查询。

知道为什么会发生这种情况以及如何解决这个问题?我的猜测是date / where子句,但我不知道这会如何影响结果。

3 个答案:

答案 0 :(得分:3)

如果要过滤记录,则需要WHERE子句:

SELECT a.*
FROM (SELECT a.*,
             row_number() over(partition by ID order by Date desc) as seqnum
      FROM tableA a
      WHERE a.Date = '20161128'
    ) a
WHERE seqnum = 1;

这将为每个ID号每个日期返回一行。

答案 1 :(得分:2)

您可以替换

SELECT *,

row_number() over(partition by ID order by Date desc)

FROM tableA

WHERE Date = 20161128

SELECT *  

FROM tableA

WHERE ID = (select min(ID) from tableA )

答案 2 :(得分:1)

这只会显示第一个实例。

Select * from
(SELECT *,
rownum=row_number() over(partition by PersonID_EXT order by SnapshotDate desc)
FROM tableA
WHERE Date = 20161128)x where rownum =1