我的任务是生成一个报告,该报告将随机选择一个唯一ID的10%,除非10%少于20个项目,在这种情况下,报告将选择20个随机ID。
我一直在使用NewID
来生成10%,但这并不是最好的,因为它给了我可变的结果(即:大于或小于10%)
代码还包括我尝试获得的结果总数:
select UniqueID, TotalCount = Count(*) Over(), SUM(COUNT(UniqueID)) OVER()
AS total_count
from table
where 0.15 >= CAST(CHECKSUM(NEWID(), UniqueID) & 0x7fffffff AS float) / CAST (0x7fffffff AS int)
group by UniqueID
答案 0 :(得分:1)
我将生成一个按new_id排序的row_number,然后计算出可以随机抽取的行数(N行)是1行。如果少于20行,则得到所有行
无论您需要查询什么内容,都将其放在 使用CTE AS(“您的查询在这里”)
并将row_number()(按newid()的顺序)作为x添加到所选列的列表中
WITH CTE AS
(select *,row_number() over (order by newid()) as x from istasks )
SELECT *
FROM CTE
CROSS APPLY
(SELECT MAX(c2.X) MX, ROUND(.1* MAX(c2.X),0) P --P is no rows needed according to 10% rule
FROM CTE C2
) DQ
WHERE CTE.X <= CASE WHEN P < 20 THEN 20 ELSE P END --take 20 rows if P < 20
答案 1 :(得分:1)
if ((select count (*) as a from (select top 10 percent * from [table]) t) < 20)
BEGIN
Select top 20 * from [table] order by newid()
END
ELSE
BEGIN
select top 10 percent * from [table] order by newid() END
答案 2 :(得分:0)
如果您不需要知道总行数,那么下面的构造可能是满足“ 10%或前20个”要求的最快方法
If (SELECT COUNT(*) FROM (
SELECT TOP 200 * -- if 10% = 20, then 100% = 200
FROM [table] ) AS top200
) < 200
BEGIN
SELECT TOP 20 ...
END
ELSE
BEGIN
SELECT TOP 10 PERCENT ...
END
请注意,内部查询中没有ORDER BY
答案 3 :(得分:0)
如果您的表中有一个UniqueID
大于1(每个COUNT(UniqueID)
)的UniqueID
,则该 UniqueID 不是唯一 ,因此查询中的TotalCount
和total_count
列应返回相同的值。
要过滤掉记录的前10%(或至少20条),可以计算一个随机行号(使用NEWID()
),然后对其应用过滤器(包括记录总数)。行数和记录总数都可以使用 window函数(带有OVER子句)进行计算,但是由于这些函数不能在WHERE子句中使用(它们会在已生成常规结果集),则计算必须在子查询中进行(可以将其写为CTE)。我的建议是尝试这样:
WITH
cte AS (
SELECT UniqueID,
RowNumber = ROW_NUMBER() OVER (ORDER BY NEWID()),
MaxNumber = COUNT(*) OVER ()
FROM YourTable
)
SELECT UniqueID
FROM cte
WHERE RowNumber <= MaxNumber/10 OR RowNumber <= 20;
如果您需要将小数值的10%值四舍五入(如TOP x PERCENT一样),请尝试使用替代的WHERE子句:
WHERE RowNumber <= (MaxNumber+9)/10 OR RowNumber <= 20;