9

我有一个大约 1000 万行和 4 列的表,没有主键。第 2 3 4 列(x2 x3 和 x4)中的数据按列 1 X1 中标识的 50 个组进行分组。

为了从表中获得 5% 的随机样本,我一直使用

SELECT TOP 5 PERCENT *
FROM thistable
ORDER BY NEWID()

结果返回大约 500,000 行。但是,如果以这种方式采样,某些组会在样本中得到不相等的表示(相对于它们的原始大小)。

这一次,为了获得更好的样本,我想从 X1 列中确定的 50 个组中的每个组中获取 5% 的样本。因此,最后,我可以获得 X1 中 50 个组中每组 5% 的行的随机样本(而不是整个表的 5%)。

我该如何解决这个问题?谢谢你。

4

1 回答 1

11

您需要能够计算每个组,然后以随机顺序强制输出数据。幸运的是,我们可以使用 CTE 样式的查询来做到这一点。尽管 CTE 不是严格需要的,但它有助于将解决方案分解成小块,而不是大量的子选择等。

我假设您已经有一个对数据进行分组的列,并且该列中的值对于组中的所有项目都是相同的。如果是这样,这样的事情可能会起作用(要更改列和表名以适应您的情况):

WITH randomID AS (
    -- First assign a random ID to all rows. This will give us a random order.
    SELECT *, NEWID() as random FROM sourceTable
),
countGroups AS (
    -- Now we add row numbers for each group. So each group will start at 1. We order 
    -- by the random column we generated in the previous expression, so you should get
    -- different results in each execution
    SELECT *, ROW_NUMBER() OVER (PARTITION BY groupcolumn ORDER BY random) AS rowcnt FROM randomID
)
-- Now we get the data
SELECT * 
    FROM countGroups c1
    WHERE rowcnt <= (
        SELECT MAX(rowcnt) / 20 FROM countGroups c2 WHERE c1.groupcolumn = c2.groupcolumn
    )

这两个 CTE 表达式允许您随机排序,然后计算每个组。最后的选择应该相当简单:对于每个组,找出其中有多少行,并且只返回其中的 5% (total_row_count_in_group / 20)。

于 2013-11-18T19:59:48.473 回答