2013-01-16 34 views
1

如何在不使用Top子句的情況下從表中選出前40%(或Top百分比,分配有點含糊)?這個問題是針對T-SQL,SQL Server 2008的。我不允許在我的任務中使用Top。如何在不使用Top子句的情況下選擇T-SQL中的Top%?

謝謝。

這是我試過的,但似乎很複雜。沒有更簡單的方法嗎?

select top (convert (int, (select round (0.4*COUNT(*), 0) from MyTable))) * from MyTable 
+3

您的任務?你有什麼嘗試? – Oded

+4

「我試過的東西」包含「TOP」 –

+0

賦值文本有點模糊不清,並且沒有指定如果我不能使用Top,只會指向Top n百分比。代碼可移植性是使用Top還是存在其他缺點的唯一缺點? – Mythul

回答

3

到目前爲止給出的NTILE(10)回答存在的一個問題是,如果表格有15行,它們將返回8行(53%)而不是正確的數字以構成40%(6)。

如果行數不能被桶的數量整除,多餘的行都會進入第一個桶中,而不是均勻分佈。

這個選擇(借用SQL威脅表)避免了這個問題。

WITH CTE 
    AS (SELECT *, 
       ROW_NUMBER() OVER (ORDER BY Score) AS RN, 
       COUNT(*) OVER()      AS Cnt 
     FROM #temp) 
SELECT StudentID, 
     Score 
FROM CTE 
WHERE RN <= CEILING(0.4 * Cnt) 
5

嘗試NTILE功能:

;WITH YourCTE AS 
(
    SELECT 
     (some columns), 
     percentile = NTILE(10) OVER(ORDER BY SomeColumn DESC) 
    FROM 
     dbo.YourTable 
) 
SELECT * 
FROM YourCTE 
WHERE percentile <= 4 

NTILE(10) OVER(....)您的數據創建10組百分比 - 因此,前40%的羣體沒有。 1,2,3,4這個結果的

+0

NTILE(10)'不會爲15行表返回正確的行數。重做爲'NTILE(5)'會減少問題,但仍不會返回7行表的正確數字。 –

4

使用NTILE

CREATE TABLE #temp(StudentID CHAR(3), Score INT) 

INSERT #temp VALUES('S1',75) 
INSERT #temp VALUES('S2',83) 
INSERT #temp VALUES('S3',91) 
INSERT #temp VALUES('S4',83) 
INSERT #temp VALUES('S5',93) 
INSERT #temp VALUES('S6',75) 
INSERT #temp VALUES('S7',83) 
INSERT #temp VALUES('S8',91) 
INSERT #temp VALUES('S9',83) 
INSERT #temp VALUES('S10',93) 

SELECT * FROM (
SELECT NTILE(10) OVER(ORDER BY Score) AS NtileValue,* 
FROM #temp) x 
WHERE NtileValue <= 4 
ORDER BY 1 

有趣的是我的博客上講述NTILE今天:Does anyone use the NTILE() windowing function?

+0

+1博客文章 –

1

計算並設定ROWCOUNT用於記錄的任何數字。 然後執行您查詢的有限集合。

declare @rc as integer 
select @rc = count(*)*0.40 from CTE 
Set ROWCOUNT @rc 
select * from CTE 

ROWCOUNT不會被棄用,但 - 見http://msdn.microsoft.com/en-us/library/ms188774.aspx

+0

你能舉一個例子SQL嗎? –

1

使用頂級T-SQL命令:

select top 10 [Column_1], 
[Column_2] from [Table] 
order by [Column_1] 

使用分頁方法:

select 
[Column_1], 
[Column_2] 
from 
    (Select ROW_NUMBER() Over (ORDER BY [Column_1]) AS Row, 
    [Column_1], 
    [Column_2] 
    FROM [Table]) as [alias] 
WHERE (Row between 0 and 10) 

這是找到了前10名按[Column_1]的順序...請注意,這是使用文檔的[變量]方法。

如果你可以提供列名和表名,我可以寫更多有益的t-sql,例如找到前40%你需要做另一個子查詢來獲得所有行的數量然後做在我做主查詢之前,我很可能會這樣做。

相關問題