从表中选择没有变量的分层样本

时间:2014-07-21 12:37:57

标签: mysql sql database infinidb

我需要得到一张大桌子的分层样本。具体来说,我想从我的表中选择1 / n行而没有偏差,即随机选择,选择每第n行等等。

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

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

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

1 个答案:

答案 0 :(得分: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;