Группировка по каждой N записи в T-SQL - PullRequest
17 голосов
/ 15 августа 2011

У меня есть некоторые результаты теста производительности в базе данных, и я хочу сгруппировать каждые 1000 записей (предварительно отсортированные в порядке возрастания по дате), а затем агрегировать результаты с AVG .

Я на самом деле ищу стандартное решение SQL, однако любые специфические результаты T-SQL также приветствуются.

Запрос выглядит так:

SELECT TestId,Throughput  FROM dbo.Results ORDER BY id

Ответы [ 3 ]

23 голосов
/ 15 августа 2011
WITH T AS (
  SELECT RANK() OVER (ORDER BY ID) Rank,
    P.Field1, P.Field2, P.Value1, ...
  FROM P
)
SELECT (Rank - 1) / 1000 GroupID, AVG(...)
FROM T
GROUP BY ((Rank - 1) / 1000)
;

Нечто подобное должно начать вас. Если вы можете предоставить вашу фактическую схему, я могу обновить ее соответствующим образом.

8 голосов
/ 15 августа 2011

Дай ответ Юку.Я публикую только как ответ, чтобы я мог включить блок кода.Я проверил подсчет, чтобы определить, группировалась ли она по 1000, а первый набор был 999. Это позволило получить наборы размером 1000.Отличный запрос гадость.

    WITH T AS (
    SELECT RANK() OVER (ORDER BY sID) Rank, sID 
    FROM docSVsys
    )
    SELECT (Rank-1) / 1000 GroupID, count(sID)
    FROM T
    GROUP BY ((Rank-1) / 1000)
    order by GroupID 
7 голосов
/ 15 августа 2011

Я + 1 @ @ Як, потому что я думаю, что это хороший ответ. Но стоит упомянуть NTILE ().

Причина в том, что если у вас есть 10 010 записей (например), то у вас будет 11 группировок - первые 10 с 1000 в них, а последняя всего с 10.

Если вы сравниваете средние значения для каждой группы из 1000, то вам следует либо отбросить последнюю группу, поскольку она не является репрезентативной, либо ... вы можете сделать все группы одинакового размера.

NTILE () сделает все группы одинакового размера; единственное предостережение - вам нужно знать, сколько групп вы хотите.

Таким образом, если бы в вашей таблице было 25 250 записей, вы бы использовали NTILE (25), и ваши группировки имели бы размер приблизительно 1000 - на самом деле они были бы размером 1010; выгода в том, что все они будут иметь размер того же , что может сделать их более релевантными друг другу с точки зрения любого сравнительного анализа, который вы делаете.

Вы можете получить свой размер группы просто

DECLARE @ntile int
SET  @ntile = (SELECT count(1) from myTable) / 1000

А затем измените подход @ Yuck с помощью замены NTILE ():

;WITH myCTE AS (
  SELECT NTILE(@ntile) OVER (ORDER BY id) myGroup,
    col1, col2, ...
  FROM dbo.myTable
)
SELECT myGroup, col1, col2...
FROM myCTE
GROUP BY (myGroup), col1, col2...
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...