确保TOP(10)百分比包括范围内每个日期的记录

时间:2016-12-27 22:01:36

标签: sql sql-server

我正在尝试完善审计方法,从上周收集10%的记录,以便对其进行审计。在此期间,我目前使用CROSS APPLY为每个办公室获得10%的折扣,但大多数记录来自前2天。为了改进审核,我想确保该范围内每天的记录都包含在10%中。

    SELECT   t1.PIC,   t1.TransID,   t1.ID,   t1.TranCode,  t1.Doc,  t1.TranDate,  t1.Operator,  t1.Office 
FROM [dbo].[Office]
CROSS APPLY
(
    SELECT TOP (10) PERCENT d2.*
    FROM ##AUDIT AS d2
    WHERE d2.Office = [dbo].[Office].CodeValue
    ORDER BY d2.TransID
) AS t1
ORDER BY [dbo].[Office].CodeValue

这对我每个办公室10%的收入很有帮助,但我需要改进它。

2 个答案:

答案 0 :(得分:0)

不要按TransId排序,这可能是增量分配的。相反,使用where获取所需的日期,然后随机订购:

SELECT . . .
FROM [dbo].[Office] CROSS APPLY
     (SELECT TOP (10) PERCENT d2.*
      FROM ##AUDIT AS d2
      WHERE d2.Office = [dbo].[Office].CodeValue AND
            d2.tranDate >= dateadd(day, -7, cast(getdate() as date))
      ORDER BY newid()
     ) t1

答案 1 :(得分:0)

这是另一种方法,不使用top...percent。伪随机分配行号(使用newID),从每个新transdate开始。使用ceiling(tot/10.0)获取包含至少10%样本的每个日期的记录数(例如,如果当天有10个或更少的记录,则为1个记录,如果有11到20个记录,则为2个记录,等),然后从初始表中选择那么多记录。

;with CTE as (
select tranDate, transID
    , count(transID) over (partition by tranDate) tot
    , row_number() over (partition by tranDate order by newid()) rn
from ##Audit)

select *
from CTE
where ceiling(tot/10.0) >= rn

如果您需要从每个办事处,每个日期或其他因素中选择10%,则可以修改查询的partition by部分。