2015-01-23 3 views
2

Я пишу сценарий, который генерирует случайные данные. У меня есть две таблицы, одна из которых хранит первые имена, а во-вторых, хранит фамилии. Я хочу получить, например. 1000 случайных пар имени и фамилии. я могу достичь этого, используя следующий код:получить случайные верхние n строк, где n больше количества строк в таблице

with x as (
    select top 1000 f.firstName from dbo.firstNames f order by newid() 
    ), xx as (
    select x.firstName, row_number() over(order by x.firstName) as nameNo from x 
    ), y as (
    select top 1000 s.surName from dbo.surNames s order by newid() 
    ), yy as (
    select y.surName, row_number() over(order by y.ulica) as nameNo from y 
    ) 
    select xx.firstName, yy.surName 
    from xx inner join yy on (xx.nameNo=yy.nameNo) 

... но что делать, если одна из моих таблиц содержит менее 1000 строк? Я задавался вопросом, как получить больше, чем n строк из таблицы, где n меньше количества строк в таблице/представлении, и вы не возражаете против повторных результатов. единственный способ, которым я мог подумать, - использовать временную таблицу и цикл while и заполнить ее случайными строками, пока не будет достаточно строк. Но мне интересно, можно ли это сделать с помощью одного выбора? Я в настоящее время использую sql-сервер 2012 на моем ПК, но я был бы признателен, если бы смог запустить его под SQL Server 2008.

+0

Это должно быть 100% sql? потому что вы можете просто получить случайное 1000 имя и случайные 1000 фамилий и быстро их объединить на прикладном уровне и даже обрабатывать короткие таблицы. – xeo

ответ

2

Если вы хотите 1000 случайных пар, то 32 из каждой таблицы должно быть достаточно (32 * 32 = 1024):

WITH f1 AS (
    SELECT TOP 32 firstName FROM dbo.firstName ORDER BY newid() 
), s1 AS 
    SELECT TOP 32 surName FROM dbo.surName ORDER BY newid() 
) 
SELECT f1.firstName, s1.surName 
    FROM f1 CROSS JOIN s1; 

Если этого не достаточно случайным образом, то вы можете попробовать следующее:

WITH f1 AS (
    SELECT TOP 100 firstName FROM dbo.firstName ORDER BY newid() 
), s1 AS 
    SELECT TOP 100 surName FROM dbo.surName ORDER BY newid() 
) 
SELECT TOP 1000 f1.firstName, s1.surName 
    FROM f1 CROSS JOIN s1 
ORDER BY newid(); 

Вышеуказанное будет иметь 10 000 комбинаций и выбрать 1000 из них в случайном порядке.

3

Вы могли бы сделать рандомизации после перекрестное соединение:

select top 1000 fn.firstname, sn.surname 
from firstnames fn cross join 
    surnames sn 
order by newid(); 

Я первый признать, что проблема с этим подходом является производительность, но он работает в теории. И производительность, вероятно, прекрасна, если таблицы имеют не более нескольких сотен строк.

+0

Добавьте 'top (1000)' к вашему запросу, и он отлично заменит исходный запрос на вопрос и, скорее всего, будет работать быстрее. –

+0

@ Владимир Баранов. , , Спасибо. Это важное дополнение. –

Смежные вопросы