SQL - 每月为n个用户提供样本

时间:2018-05-29 23:31:37

标签: sql presto

我目前正在使用具有属性(user_idcreated_at,...)的表格。我想抽样说自去年11月以来每个月创建的100到200个用户。如果我只从一个月中选择100个用户,那将很容易,因为我可以这样做:

select * from TABLE where created_at >= 'xxxx' and created_at <= 'xxxx'

但我想不出一个干净的方法来每个月做这个,然后把结果放在一起。这有可能以任何方式用SQL实现吗?非常感谢你。

4 个答案:

答案 0 :(得分:3)

如果您的日期确实存储为字符串2018-01-01,那么您可以使用字符串的前7个字符来获取月份。

然后,使用ROW_NUMBER按月分区,每月挑选前100名用户。

SELECT
    user_id,
    created_at
FROM
    (
        SELECT
            user_id,
            created_at,
            ROW_NUMBER() OVER (PARTITION BY substr(created_at, 1, 7) ORDER BY user_id) AS rn
        FROM T
        WHERE created_at >= '2017-11-01'
    ) AS R
WHERE
    rn <= 100
;

ORDER BY定义要选择的用户。上面的查询按其ID选择前100名用户,这可能是按创建顺序排列的,因此查询基本上会选择每月创建的前100个用户。

如果您想要一些随机选择,请通过返回随机数的函数进行排序。这看起来更像是一个“样本”。

SELECT
    user_id,
    created_at
FROM
    (
        SELECT
            user_id,
            created_at,
            ROW_NUMBER() OVER (PARTITION BY substr(created_at, 1, 7) ORDER BY random()) AS rn
        FROM T
        WHERE created_at >= '2017-11-01'
    ) AS R
WHERE
    rn <= 100
;

答案 1 :(得分:0)

使用ROW_NUMBER

SELECT user_id, created_at    -- and other columns
FROM
(
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY DATE_FORMAT(created_at, '%Y %m')
            ORDER BY created_at DESC) rn
    FROM yourTable
) t
WHERE t.rn <= 100 AND created_at >= '2017-11-01';

我们使用MySQL函数DATE_FORMAT创建每个月和每年的分区,然后我们只保留每个分区的100个用户。

答案 2 :(得分:0)

假设t-sql和created_at是一个日期时间。 您可以使用ROW_NUMBER()(取决于您可以使用几个不同的排名/行类型函数后的特定行为)来为每个年/月组合生成行号。 https://docs.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql?view=sql-server-2017

Declare @rows int = 100,
    @date datetime = '2017-11-30'
SELECT *
FROM [YourTable] t
WHERE EXISTS (
    SELECT *
    from(
        Select user_id,
            ROW_NUMBER()OVER(PARTITION BY DATEPART(YEAR, created_at), DATEPART(MONTH, created_at) ORDER BY created_at) as rn
        FROM [YourTable]
        WHERE created_at > @date
        ) as ds
    Where rn <= @rows
    and ds.user_id = t.user_id
    )

编辑:在指定rdbms之前编写,我将把它留在这里以防万一其他人偶然发现,除非不合适。

答案 3 :(得分:0)

这是一个关于使用NTILE和TABLESAMPLE的博客,我认为这正是你所需要的(分层恒定比例抽样)。

data-sampling-in-presto