SQL数据抽样

问题描述:

我们已经向外部公司提供了一些数据。 他们只需要一个数据样本,简单的权利?错误。SQL数据抽样

这里是他们取样标准:

  • 的由720(所需的样本大小)除以记录总数 - 这使采样间隔(如果结果是一小部分,向下舍入到下一个整数)。

  • 减半采样间隔以获得起点。

  • 通过在采样间隔上添加来返回每条记录。

实施例:

  • 万记录 - 采样间隔= 13(10,000/720)
  • 起点= 6(13/2四舍五入)
  • 返回记录6,19(6+ 13),32(19 + 13),45(32 + 13)等.....

请可有人告诉我如何(如果)这样的事情是可能的SQL。

+0

什么牌子的SQL?如果你有ROW_NUMBER()会有很大的帮助。此外,如果采样间隔为720,并且定义的起始点***意味着数据有一个顺序 - 那么数据应该以什么顺序出现? – MatBailie 2012-02-23 12:54:50

+0

ROW_NUMBER()OVER(按TransactionDate排序)AS RowNumber, – 2012-02-23 12:57:17

如果你有使用ROW_NUMBER(),那么你可以做到这一点相对容易。

SELECT 
    * 
FROM 
(
    SELECT 
    ROW_NUMBER() OVER (ORDER BY a, b, c, d) AS record_id, 
    * 
    FROM 
    yourTable 
) 
    AS data 
WHERE 
    (record_id + 360) % 720 = 0 

ROW_NUMBER()给您所有的数据顺序标识符(这是id字段都必须是唯一的,并没有任何的差距很重要)。它还定义了你想要的数据的订单号码为(ORDER BY a, b, c, d)

使用该编号,如果使用Modulo(通常是%运算符),则可以测试记录是第720条记录,第1440条记录等(因为720%720 = 0)。

然后,如果您将id值减去360,则可以更改结果集的起点。

编辑

重新阅读的问题后,我看你不希望每次720次的纪录,但均匀选择720分的记录。

这样,与(SELECT COUNT(*)/720 FROM yourTable)

替换720并与(SELECT (COUNT(*)/720)/2 FROM yourTable)

EDIT

取代360忽略的舍入条件将允许的准确720记录的结果。这要求使用非整数值,并且模的结果小于1。

WHERE 
    (record_id + (SELECT COUNT(*) FROM yourTable)/1440.0) 
    % 
    ((SELECT COUNT(*) FROM yourTable)/720.0) 
    < 
    1.0 
+0

确定。因此,我对收集的数据运行我的查询以返回 - 这给了我9353条记录。采样间隔应该是12,起始点应该是6.当我添加你的代码时,我得到779行返回,有什么想法? – 2012-02-23 13:08:39

+0

@Richard - 779行是因为您需要将采样间隔舍入为整数。 '9353/720 = 12.99' =>'12'。然后,“9353/12 = 779.33”=>“779”。你知道哪一部分最重要吗?舍入取样间隔,或返回720条记录? *** [这是不可能的] *** – MatBailie 2012-02-23 13:15:01

+0

从数据请求,我会说720是目标。 – 2012-02-23 13:17:35

declare @sample_size int, @starting_point int 

select @sample_size = 200 

select top (@sample_size) col1, col2, col3, col4 
from (
    select *, row_number() over (order by col1, col2) as row 
    from your_table 
) t 
where (row % ((select count(*) from your_table)/@sample_size)) - (select count(*) from your_table)/@sample_size/2) = 0 

这将在SQL Server 2005+的工作。

TOP (@variable)用于限制行(where条件,因为四舍五入可能不够,可能会返回更多行,然后需要)和ROW_NUMBER()来编号和排序行。

工作例如:http://data.stackexchange.com/*/query/62315/sql-data-sampling下面的代码:

declare @tab table (id int identity(1,1), col1 varchar(3), col2 varchar(3)) 

declare @i int 

set @i = 0 

while @i <= 1000 
begin 
    insert into @tab 
    select 'aaa', 'bbb' 
    set @i = @i+1 
end 

declare @sample_size int 

select @sample_size = 123 

select ((select count(*) from @tab)/@sample_size) as sample_interval 

select top (@sample_size) * 
from (
    select *, row_number() over (order by col1, col2, id desc) as row 
    from @tab 
) t 
where (row % ((select count(*) from @tab)/@sample_size)) - ((select count(*) from @tab)/@sample_size/2) = 0 
+0

我想知道为什么“-1”,你能解释一下吗?也许我学到了新的东西。 – 2012-02-23 13:16:27

+0

您的解决方案很好,但是我的原因是它不是一个动态的方法。 SP应该真的自己计算出发点。 – 2012-02-23 13:21:57

+0

@Richard,好吧,误读,但容易纠正和纠正。为了您的更新,删除了 – 2012-02-23 13:37:45

您可以使用排名来获得的行数。以下代码将在表中创建10000条记录,然后选择第6,第19和第32等,共计769行。

CREATE TABLE Tbl (
    Data varchar (255) 
) 
GO 

DECLARE @i int 
SET @i = 0 
WHILE (@i < 10000) 
BEGIN 
    INSERT INTO Tbl (Data) VALUES (CONVERT(varchar(255), NEWID())) 
    SET @i = @i + 1 
END 
GO 

DECLARE @interval int 
DECLARE @start int 
DECLARE @total int 
SELECT @total = COUNT(*), 
     @start = FLOOR(COUNT(*)/720)/2, 
     @interval = FLOOR(COUNT(*)/720) 
FROM Tbl 

PRINT 'Start record: ' + CAST(@start as varchar(10)) 
PRINT 'Interval: ' + CAST(@interval as varchar(10)) 

SELECT rank, Data 
FROM (
    SELECT rank() 
    OVER (ORDER BY t.Data) as rank, t.Data AS Data 
    FROM Tbl t) q 
WHERE ((rank + 1) + @start) % @interval = 0 
+0

为什么RANK()?如果记录具有相同的排名值,则会导致冲突,并且具有相同RANK()的多个值。这可能导致过度选择(具有感兴趣的RANK()的多个值)和选择不足(由于该等级实际上在另一个位置处的联系而失去等级)。只需使用ROW_NUMBER()? – MatBailie 2012-02-23 13:25:11

SQL服务器具有内置函数。选择名,姓
选择名,姓 从Person.Person TABLESAMPLE(10 PERCENT);