SQL数据抽样
我们已经向外部公司提供了一些数据。 他们只需要一个数据样本,简单的权利?错误。SQL数据抽样
这里是他们取样标准:
的由720(所需的样本大小)除以记录总数 - 这使采样间隔(如果结果是一小部分,向下舍入到下一个整数)。
减半采样间隔以获得起点。
- 通过在采样间隔上添加来返回每条记录。
实施例:
- 万记录 - 采样间隔= 13(10,000/720)
- 起点= 6(13/2四舍五入)
- 返回记录6,19(6+ 13),32(19 + 13),45(32 + 13)等.....
请可有人告诉我如何(如果)这样的事情是可能的SQL。
如果你有使用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
确定。因此,我对收集的数据运行我的查询以返回 - 这给了我9353条记录。采样间隔应该是12,起始点应该是6.当我添加你的代码时,我得到779行返回,有什么想法? – 2012-02-23 13:08:39
@Richard - 779行是因为您需要将采样间隔舍入为整数。 '9353/720 = 12.99' =>'12'。然后,“9353/12 = 779.33”=>“779”。你知道哪一部分最重要吗?舍入取样间隔,或返回720条记录? *** [这是不可能的] *** – MatBailie 2012-02-23 13:15:01
从数据请求,我会说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/stackoverflow/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
我想知道为什么“-1”,你能解释一下吗?也许我学到了新的东西。 – 2012-02-23 13:16:27
您的解决方案很好,但是我的原因是它不是一个动态的方法。 SP应该真的自己计算出发点。 – 2012-02-23 13:21:57
@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
为什么RANK()?如果记录具有相同的排名值,则会导致冲突,并且具有相同RANK()的多个值。这可能导致过度选择(具有感兴趣的RANK()的多个值)和选择不足(由于该等级实际上在另一个位置处的联系而失去等级)。只需使用ROW_NUMBER()? – MatBailie 2012-02-23 13:25:11
SQL服务器具有内置函数。选择名,姓
选择名,姓 从Person.Person TABLESAMPLE(10 PERCENT);
什么牌子的SQL?如果你有ROW_NUMBER()会有很大的帮助。此外,如果采样间隔为720,并且定义的起始点***意味着数据有一个顺序 - 那么数据应该以什么顺序出现? – MatBailie 2012-02-23 12:54:50
ROW_NUMBER()OVER(按TransactionDate排序)AS RowNumber, – 2012-02-23 12:57:17