SQL数据采样

SQL数据采样,sql,Sql,我们已接到向外部公司提供一些数据的请求。 他们只需要一个数据样本,很简单吧?错 以下是他们的抽样标准: 记录总数除以720所需样本量-如果结果是分数,则给出采样间隔,四舍五入到下一个整数 将采样间隔减半以获得起点 通过添加采样间隔返回每条记录。 例如: 10000条记录-采样间隔=13 10000/720 起点=6 13/2四舍五入 返回记录6、19 6+13、32 19+13、45 32+13等。。。。。 请有人告诉我,如果在SQL中这样做是如何可能的。如果您使用了行号,那么您可以相对轻松地执

我们已接到向外部公司提供一些数据的请求。 他们只需要一个数据样本,很简单吧?错

以下是他们的抽样标准:

记录总数除以720所需样本量-如果结果是分数,则给出采样间隔,四舍五入到下一个整数

将采样间隔减半以获得起点

通过添加采样间隔返回每条记录。 例如:

10000条记录-采样间隔=13 10000/720 起点=6 13/2四舍五入 返回记录6、19 6+13、32 19+13、45 32+13等。。。。。
请有人告诉我,如果在SQL中这样做是如何可能的。

如果您使用了行号,那么您可以相对轻松地执行此操作

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字段必须是唯一的,并且没有任何间隙。它还定义了您希望数据按a、b、c、d顺序排列的顺序

使用该id,如果您经常使用模运算%运算符,则可以测试该记录是否为第720条记录、第1440条记录等,因为720%720=0

然后,如果将id值偏移360,则可以更改结果集的起点

编辑

在重读了这个问题之后,我发现您并不想要每一条720条记录,而是统一选择了720条记录

同样,将720替换为表中的SELECT COUNT*/720

将360替换为表中的SELECT COUNT*/720/2

编辑

忽略舍入条件将允许正好720条记录的结果。这需要使用非整数值,并且模的结果小于1

WHERE
  (record_id + (SELECT COUNT(*) FROM yourTable) / 1440.0)
  %
  ((SELECT COUNT(*) FROM yourTable) / 720.0)
  <
  1.0
它将在SQLServer2005+中工作

用于限制由于整数舍入而导致的条件可能不够的行,可能返回比需要的行更多的行,并对行进行编号和排序

工作示例:以下代码:

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

您可以使用秩来获取行号。下面的代码将在一个表中创建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

SQL server具有内置的功能。 选择FirstName,LastName 来自个人,个人
样本10%

什么品牌的SQL?如果你有排号,那会很有帮助。此外,采样间隔为720,定义的起点意味着数据有一个顺序-那么,您的数据应该以什么顺序出现?行数超过订单,按TransactionDate显示为行数,好的。因此,我对收集的数据运行查询以返回-这给了我9353条记录。采样间隔应为12,起点应为6。当我添加您的代码时,返回了779行,有什么想法吗?@Richard-779行是因为您需要将采样间隔舍入为整数。9353 / 720 = 12.99 => 12. 然后,9353/12=779.33=>779。你知道哪个部分最重要吗?舍入采样间隔,还是只返回720条记录?[不可能两者都有。]根据数据请求,我会说720是目标。@Richard-答案更新为返回720条记录,而不是执行请求的舍入。非常感谢您的帮助!我想知道为什么-1,你能解释一下吗?也许我学到了一些新的东西。你的解决方案很好,但I-1的原因是它不是一个动态的方法。SP应该自己计算起点。为什么要排名?如果记录具有相同的排名值,这将导致冲突,以及具有相同排名的多个值。这可能导致过度选择多个具有感兴趣等级的值,以及选择不足缺少等级,因为该等级实际上是另一位置的平局。就用排号?
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