SQL Сервер для возврата набора из 10 лучших записей - PullRequest
1 голос
/ 14 июля 2020

У меня есть таблица с данными, подобными приведенной ниже:

ID        Name
1         abc
1         xyz
2         abc
2         xyz 
2         pqr
3         abc
3         xyz
3         pqr
3         mno
3         stu
3         def

Теперь я хочу, чтобы результат возвращал только 10 лучших записей, набор которых полностью извлекается с помощью этого запроса. Например, я хочу, чтобы результат для первых 10 записей был:

ID        Name
1         abc
1         xyz
2         abc
2         xyz
2         pqr

, а для следующего набора результатов из 10 лучших он должен быть:

ID      Name
3       abc
3       xyz
3       pqr
3       mno
3       stu
3       def

Ответы [ 2 ]

0 голосов
/ 23 июля 2020

Я закончил тем, что написал ниже запрос для моего собственного вопроса выше

Declare @OutputTable TABLE (ID int, NAME NVarchar(50))
Declare @ID int, @total int, @tempTotal int, @count int, @minrownumb int, @outputcount int = 0
DECLARE @result table (ID int, NAME NVarchar(50), Total int, RowNumb int)
SELECT @tempTotal = 0, @count = 1

INSERT INTO @result
SELECT ID, NAME, total, ROW_NUMBER() OVER (ORDER BY ID ASC) FROM 
    ( 
        SELECT ID, NAME, ID, count(ID) total from MyTable WHERE NAME IS NOT NULL GROUP BY ID, NAME, ROLLUP(ID)
    ) A WHERE ID IS NULL

SELECT @minrownumb = min(RowNumb) from @result
SELECT @maxcount = CASE WHEN @maxcount > SUM(total) THEN SUM(total) ELSE @maxcount End FROM @result

WHILE @Temptotal <= @maxcount 
BEGIN
    SELECT @ID=ID, @total = Total FROM @result WHERE RowNumb = @count       
    IF (@total >=  @maxcount AND @count = @minrownumb)
        INSERT INTO @OutputTable 
            SELECT ID, NAME FROM dbo.MyTable WHERE ID = @ID
    ELSE
    BEGIN
        IF (@total + @outputcount <= @maxcount)
            INSERT INTO @OutputTable SELECT ID, NAME  FROM dbo.MyTable WHERE ID = @ID
    END

    SET @Temptotal = @Temptotal + @total
    SET @count = @count+1

    SELECT @outputcount = Count(1) FROM @OutputTable
END

Он дал мне результаты в виде фрагментов идентификатора, которые помещаются либо в одну корзину из 10 записей или меньше.

0 голосов
/ 14 июля 2020

Мы можем сгруппировать данные в сегменты по 10, как показано ниже:

declare @table table(id int, name varchar(10))

INSERT INTO @table values
(1 ,'abc'),
(1 ,'xyz'),
(2 ,'abc'),
(2 ,'xyz'), 
(2 ,'pqr'),
(3 ,'abc'),
(3 ,'xyz'),
(3 ,'pqr'),
(3 ,'mno'),
(3 ,'stu'),
(3 ,'def');

DECLARE @Tengroups int = (SELECT COUNT(*)/10 FROM @table)
--select @Tengroups, @RemainderTenGroups
select ID, NAME, NTILE(@Tengroups) over (order by rnk) as bucket from
(SELECT ID,NAME, row_number() over(order by id) as rnk FROM @table) as t
where rnk <= @tengroups * 10
-- remaining data, which was not in groups of 10 buckets. It will be new bucket
UNION ALL
select ID, NAME, @Tengroups + 1 as bucket from
(SELECT ID,NAME, row_number() over(order by id) as rnk FROM @table) as t
where rnk > @tengroups * 10

+----+------+--------+
| ID | NAME | bucket |
+----+------+--------+
|  1 | abc  |      1 |
|  1 | xyz  |      1 |
|  2 | abc  |      1 |
|  2 | xyz  |      1 |
|  2 | pqr  |      1 |
|  3 | abc  |      1 |
|  3 | xyz  |      1 |
|  3 | pqr  |      1 |
|  3 | mno  |      1 |
|  3 | stu  |      1 |
|  3 | def  |      2 |
+----+------+--------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...