SQL - 5% случайной выборки по группам

У меня есть таблица с примерно 10 миллионами строк и 4 столбцами, без первичного ключа. Данные в столбце 2 3 4 (x2 x3 и x4) сгруппированы по 50 группам, указанным в столбце 1 X1.

Чтобы получить случайную выборку 5% из таблицы, я всегда использовал

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

Результат возвращает около 500 000 строк. Но некоторые группы получают неравное представление в выборке (относительно их первоначального размера), если выборка выполняется таким образом.

На этот раз, чтобы получить лучшую выборку, я хотел получить 5% выборки из каждой из 50 групп, указанных в столбце X1. Итак, в конце я могу получить случайную выборку из 5% строк в каждой из 50 групп в X1 (вместо 5% всей таблицы).

Как я могу подойти к этой проблеме? Спасибо.

1 ответ

Решение

Вы должны иметь возможность подсчитать каждую группу и затем вывести данные в случайном порядке. К счастью, мы можем сделать это с помощью запроса в стиле 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).

Другие вопросы по тегам