#sql #sql-server #tsql #sql-server-2008
#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 )
Мне нужно выбрать первые три строки для каждого внешнего идентификатора, обновить их значение 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'
Ответ №1:
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 вложенное значение уникально
Ответ №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. Потрясающе, CTE находятся там, где они есть. Спасибо!
Ответ №3:
Используйте функции ранжирования, в частности ROW_NUMBER
, чтобы ограничить количество возвращаемых результатов.