T-Sql Select * От 30% до 40% - PullRequest
       37

T-Sql Select * От 30% до 40%

6 голосов
/ 09 июля 2010

Вопрос

  • Как написать хранимую процедуру T-SQL, которая позволяет мне выбирать проценты строк между X% и Y%?
  • Так что в основном я хотел бы выбратьстроки между 30 и 40 процентами .....

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

SELECT TOP 50 PERCENT * FROM tblAssets 

Помощь с благодарностью.

Ответы [ 2 ]

13 голосов
/ 09 июля 2010

Обновленный ответ

declare @NumRecords int
SELECT @NumRecords = COUNT(*) FROM tblAssets;

With Vals As
(
SELECT tblAssets.AssetId ...
, ROW_NUMBER() OVER ( order by tblAssets.AssetId) as RN
  FROM tblAssets
)

SELECT  tblAssets.AssetId ...
FROM vals 
Where RN between 0.3*@NumRecords and 0.4*@NumRecords

Я обновил свой ответ, так как было 2 проблемы с моим исходным ответом ниже

  1. Производительность - было побито вложенным TOP решением
  2. Точность - есть неожиданный аспект NTILE, о котором я не знал

Если количество строк в разделе не делится на integer_expression, это приведет к группы двух размеров, которые отличаются на один член. Большие группы приходят раньше меньшие группы в указанном порядке по предложению OVER. Например, если общее количество строк составляет 53 и количество групп пять, первое три группы будут иметь 11 строк и две оставшиеся группы будут иметь 10 строк каждый.

Я получил следующие значения по сравнению с вложенным решением TOP.

SET STATISTICS IO ON
SET STATISTICS TIME ON;

DECLARE @NumRecords int
SELECT @NumRecords = COUNT(*) FROM [master].[dbo].[spt_values];

WITH Vals As
(
SELECT  [number]
, ROW_NUMBER() OVER ( order by [number]) as RN
  FROM [master].[dbo].[spt_values]
)

SELECT [number] FROM vals Where RN
 BETWEEN 0.30*@NumRecords AND 0.40*@NumRecords

Придает

Таблица 'spt_values'. Количество сканирований 1, логическое чтение 8, физическое чтение 0, опережающее чтение - 0, логическое чтение - 0, lob физическое чтение 0, lob упреждающее чтение читает 0.

Таблица 'spt_values'. Сканирование 1, логическое читает 5, физический читает 0, чтение вперед читает 0, lob логическое чтение 0, lob физическое чтение 0, чтение опережающего чтения 0.

SELECT TOP 25 PERCENT [number] FROM
(
SELECT TOP 40 PERCENT  [number]
FROM  [master].[dbo].[spt_values]
ORDER BY [number]  ASC
) TOP40
ORDER BY [number] DESC

Придает

Таблица «Рабочий стол». Количество сканирований 1, логическое чтение 4726, физическое чтение 0, опережающее чтение - 0, логическое чтение - 0, lob физическое чтение 0, lob упреждающее чтение читает 0.

Таблица 'spt_values'. Сканирование 1, логическое читает 8, физический читает 0, чтение вперед читает 0, lob логическое чтение 0, lob физическое чтение 0, чтение опережающего чтения 0.

Оригинальный ответ

With Vals As
(
SELECT tblAssets.AssetId ...
, NTILE (100)  OVER ( order by tblAssets.AssetId) as Pct
  FROM tblAssets 
)

SELECT * FROM vals Where Pct between 30 and 40
0 голосов
/ 09 июля 2010

Я сам придумал это .......

SELECT TOP 40 *  
    INTO #TOP40
    FROM CCDtblAssets

 SELECT * FROM #TOP40
WHERE ASSETID NOT IN   
(SELECT TOP 30 ASSETID FROM #TOP40)

Хотя мне действительно нравится Martins Answer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...