0

我需要对我的大桌子进行分层样本。具体来说,我想从我的表中选择 1/n 行而不带偏见,即随机选择,选择每第 n 行,等等。

在我问这个问题之前,我尝试过这样。但是,它对我不起作用,因为我使用的是 InfiniDB 引擎,而且正如我后来发现的那样,它不支持子表达式中的变量或类似的东西。有谁知道没有用户变量的方法?

我在想这样的事情:在我的表中,每一行都有一个唯一的字母数字字符串id,它可以看起来像"1234567890",或者像"abcdef12345"。我正在考虑以某种方式将该字符串转换为数字,然后使用模函数从我的表中仅选择 1/n 行。但是,我不知道如何进行转换,因为这个字符串不是十六进制的。

注意:我的表没有自动增量列。

4

1 回答 1

3

这很复杂,但你可以做到。它需要自连接和聚合,在此查询中使用相关子查询实现。我的猜测是这不会很好,因为你大概有一张大桌子。对于 10% 的样本,它看起来像:

select ht.*,
       (select count(*)
        from hugetable ht2
        where ht2.col < ht.col or
              (ht2.col = ht.col and ht2.id <= ht.id)
       ) as rn
from hugetable ht
having rn % 10 = 1;

请注意,having在此上下文中的使用特定于 MySQL。它允许您在不使用子查询的情况下过滤行。

编辑:

可能唯一可行的方法——你可以做到——是创建另一个具有自动递增 id 的表。这是一个精简版:

create table temp (
    id int auto_increment,
    idstring varchar(255),
    col varchar(255)
);

insert into temp(idstring, col)
    select idstring, col
    from hugetable ht
    order by col;

select *
from temp
where id % 10 = 1;
于 2014-07-21T13:39:38.817 回答