SQL - выборка n пользователей за каждый месяц - PullRequest
0 голосов
/ 30 мая 2018

В настоящее время я работаю с таблицей, имеющей атрибуты (user_id, created_at, ...).Я хотел бы привести, например, от 100 до 200 пользователей, которые создаются в каждом месяце с ноября прошлого года.Если бы я выбрал 100 пользователей из одного месяца, это было бы легко, потому что я мог просто сделать это:

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

Но я не мог придумать, как сделать это для каждого месяца, а затемположить результаты вместе.Можно ли каким-либо образом добиться этого с помощью SQL?Большое спасибо.

Ответы [ 4 ]

0 голосов
/ 30 мая 2018

Вот блог об использовании NTILE и TABLESAMPLE, который, я думаю, именно то, что вам нужно здесь (выборочная стратифицированная пропорция).

выборка данных в предварительном режиме

0 голосов
/ 30 мая 2018

Если ваши даты действительно хранятся в виде строк 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 определяет, каких пользователей выбрать.Приведенный выше запрос выбирает 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
;
0 голосов
/ 30 мая 2018

Предполагая, что t-sql и create_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 был указан, я оставлю это здесь на случай, если кто-то наткнется, если не уместно.

0 голосов
/ 30 мая 2018

Использование 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 пользователей из каждого раздела.

...