【问题标题】:Select stratified sample from table without variables从没有变量的表中选择分层样本
【发布时间】:2014-07-21 12:37:57
【问题描述】:

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

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

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

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

【问题讨论】:

  • 选择每第 n 行不是随机的。
  • @DanBracuk 没错,但它也完全没有偏见,并提供了分层样本,这正是我想要的。
  • 您的字母数字字符串是十六进制且完全连续的吗?
  • @Arth 不,遗憾的是它不是十六进制的。但是,如果您所说的连续是指“没有空格”,那么是的。
  • 如何确定给每个值赋予哪个字母数字字符串?

标签: mysql sql database infinidb


【解决方案1】:

这很复杂,但你可以做到。它需要自连接和聚合,在此查询中使用相关子查询实现。我的猜测是这不会很好,因为你大概有一张大桌子。对于 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;

【讨论】:

  • 谢谢!我会尝试第一种方式,但第二种方式行不通,因为 InfiniDB 不支持 AUTO_INCREMENT 等约束。
  • @GordonLinoff 您在第一种方法中从哪里获得ht1?这不应该是ht吗?
  • @Arth 。 . .让我们称之为错字。它应该与外部别名 ht 相关联。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 2019-07-13
  • 2018-01-11
  • 2023-03-17
  • 2022-01-08
  • 2010-10-30
相关资源
最近更新 更多