为每个ID和日期选择前2个不同

时间:2016-11-08 12:03:08

标签: sql-server distinct partition

我有一张这样的表:

表1:

  [Id]        [TDate]     [Score]
    1         1.1.00       50
    1         1.1.00       60
    2         1.1.01       50
    2         1.1.01       70
    2         1.3.01       40
    3         1.1.00       80
    3         1.1.00       30
    3         1.2.00       40

我想要的输出应该是这样的:

[ID]  [TDate]    [Score]
1         1.1.00       60
2         1.1.01       70
2         1.3.01       40
3         1.1.00       80
3         1.2.00       40

所以,我写过这个:

SELECT DISTINCT TOP 2 Id, TDate, Score
FROM
(   SELECT Id, TDate, Score, ROW_NUMBER() over(partition by TDate order by Score) Od
    FROM Table1
) A
WHERE A.Od = 1
ORDER BY Score

但它给了我:

[ID]  [TDate]    [Score]
2         1.1.01       70
3         1.1.00       80

当然我可以这样做:

"select top 2 ...where ID = 1" 

然后:

 union 
`"Select top 2 ... where ID = 2"`

等。 但我有10万这个......

任何方式将其推广到任何Id? 谢谢。

4 个答案:

答案 0 :(得分:0)

你的输出没有意义。我假设你想要每个id两行。然后查询看起来像:

SELECT TOP 2 Id, TDate, Score
FROM (SELECT Id, TDate, Score,
             ROW_NUMBER() over (partition by id order by Score DESC) as seqnum
      FROM Table1
     ) t
WHERE seqnum <= 2
ORDER BY Score;

注意:

  • 这假设您需要每id行两行。因此,id位于PARTITION BY
  • WHERE现在在PARTITION BY
  • 中为每个组选择两行
  • 外部查询中不需要SELECT DISTINCT - 至少对于这个问题。

答案 1 :(得分:0)

WITH TOPTWO AS (
    SELECT Id, TDate, Score, ROW_NUMBER() 
    over (
        PARTITION BY TDate 
        order by SCORE
    ) AS RowNo 
    FROM [table_name]
)
SELECT * FROM TOPTWO WHERE RowNo <= 2

答案 2 :(得分:0)

除非我遗漏了某些东西,否则可以通过一个简单的小组来完成

首先,我准备一个临时表进行测试:

declare @table table (ID int, TDate varchar(10), Score int)
insert into @Table values(1, '1.1.00', 50)
insert into @Table values(1, '1.1.00', 60)
insert into @Table values(2, '1.1.01', 50)
insert into @Table values(2, '1.1.01', 70)
insert into @Table values(2, '1.3.01', 40)
insert into @Table values(3, '1.1.00', 80)
insert into @Table values(3, '1.1.00', 30)
insert into @Table values(3, '1.2.00', 40)

现在让我们在这个表上做一个选择

select ID, TDate, max(Score) as Score
from   @table
group by ID, TDate
order by ID, TDate

结果如下:

ID  TDate   Score   
1   1.1.00  60  
2   1.1.01  70  
2   1.3.01  40  
3   1.1.00  80  
3   1.2.00  40  

所以你需要做的就是将@table更改为你的表名,然后你就完成了

答案 3 :(得分:0)

尝试此操作:按ID和TDate进行分区,然后按降序排序

 ROW_NUMBER() over(partition by ID,TDate order by Score DESC) Od

完整的脚本

WITH CTE AS(

    SELECT  *,
            ROW_NUMBER() over(partition by ID,TDate order by Score DESC) RN
    FROM TableName
 ) 
 SELECT *
 FROM CTE 
 WHERE RN = 1