SQL Server在子集中选择顶部?

时间:2011-05-08 04:43:54

标签: sql sql-server tsql sql-server-2008

我有这些数据:

Create Table #Some ( ForeignId Int , SubValue UniqueIdentifier , WasRead Bit)
Insert Into #Some Values ( 1 , 'ADEE70A8-E804-4A0C-93AD-00CCCB3DA7DA' , 0 )
Insert Into #Some Values ( 1 , '024EDED5-744B-497A-BFB8-06A0C62DE0AE' , 0 )
Insert Into #Some Values ( 1 , 'C3F255F9-3648-4D8D-8D84-0951BD2D0551' , 0 )
Insert Into #Some Values ( 1 , '25CE8E67-A263-409E-8E7F-1A814EF76524' , 0 )
Insert Into #Some Values ( 2 , '1B339D13-B580-4660-9642-0C0FA9C84D14' , 0 )
Insert Into #Some Values ( 2 , '579C5BD3-EE3A-4789-A57B-0FAD0F7227A2' , 0 )
Insert Into #Some Values ( 3 , '31D1E0F2-5F8A-451B-8114-14DB685E9F53' , 0 )
Insert Into #Some Values ( 3 , '52347A60-4156-401F-8570-15554DD905EF' , 0 )
Insert Into #Some Values ( 3 , '6ECD072E-BC43-4A4C-AACD-1A6C256DCFDE' , 0 )
Insert Into #Some Values ( 3 , '3264625D-94CE-4798-9E4B-2672EDE496BC' , 0 )

我需要为每个ForeignId选择前三行,将其WasPolled值更新为1,并发出多个结果集,但所有集合的总大小不能超过8:

组:

1 , 'ADEE70A8-E804-4A0C-93AD-00CCCB3DA7DA' 
1 , '024EDED5-744B-497A-BFB8-06A0C62DE0AE' 
1 , 'C3F255F9-3648-4D8D-8D84-0951BD2D0551' 

组:

2 , '1B339D13-B580-4660-9642-0C0FA9C84D14' 
2 , '579C5BD3-EE3A-4789-A57B-0FAD0F7227A2' 

组:

3 , '31D1E0F2-5F8A-451B-8114-14DB685E9F53' 
3 , '52347A60-4156-401F-8570-15554DD905EF' 
3 , '6ECD072E-BC43-4A4C-AACD-1A6C256DCFDE' 

3 个答案:

答案 0 :(得分:2)

这是你更新前三行的方法 - 你需要提供一种排序数据的方法:

WITH example AS (
  SELECT t.*, 
         ROW_NUMBER() OVER(PARTITION BY t.foreignid 
                               ORDER BY t.subvalue) AS rank
    FROM #some t)
UPDATE example
   SET wasread = 1
 WHERE rank BETWEEN 1 AND 3

“发出多个结果集,但所有集合的总大小不能超过8:” - 嗯?!你是什​​么意思“发射”。选择意味着单独的声明:

非CTE版本:

  SELECT x.*
    FROM (SELECT t.*, 
                 ROW_NUMBER() OVER(PARTITION BY t.foreignid 
                                       ORDER BY t.subvalue) AS rank
            FROM #some t) x
   WHERE x.rank BETWEEN 1 AND 8

CTE版本:

WITH example AS (
  SELECT t.*, 
         ROW_NUMBER() OVER(PARTITION BY t.foreignid 
                               ORDER BY t.subvalue) AS rank
    FROM #some t)
SELECT e.*
  FROM example e
 WHERE e.rank BETWEEN 1 AND 8

答案 1 :(得分:2)

with cte as
(
    select ForeignId, SubValue, row_number() over(partition by ForeignId order by SubValue) as RowNumber
    from #Some
    where WasRead = 0
)
update top (8) s
set WasRead = 1
from #Some s
    join cte on
        cte.ForeignId = s.ForeignId and cte.SubValue = s.SubValue
where cte.RowNumber <= 3;

我不知道你是否有主键。如果你确实用它来加入。我假设ForeignId + SubValue是唯一的

答案 2 :(得分:0)

使用Ranking Functions,尤其是ROW_NUMBER来限制返回的结果数量。