Генерация случайных тестовых данных с помощью ORDER BY NEWID (), включая повторяющиеся строки - PullRequest
4 голосов
/ 09 мая 2019

Мне нужно выбрать случайные строки из таблицы для тестовых данных.Могут быть случаи, когда мне нужно больше строк тестовых данных, чем записей в таблице.Дубликаты в порядке.Как мне структурировать мой выбор, чтобы я мог получить повторяющиеся строки?

CREATE TABLE [Northwind].[dbo].[Persons]
(PersonID int, LastName varchar(255))

INSERT INTO [Northwind].[dbo].[Persons] 
VALUES
(1, 'Smith'), 
(2, 'Jones'),
(3, 'Washington')

SELECT TOP 5 *
FROM [Northwind].[dbo].[Persons]  
ORDER BY NEWID()

Как получить оператор Select, чтобы получить пять записей в случайном порядке с повторениями?В настоящее время он возвращает только три в случайном порядке.

Я хотел бы иметь возможность расширить это, чтобы получить 100 строк или 1000 строк или столько, сколько мне нужно.

Ответы [ 4 ]

3 голосов
/ 09 мая 2019

Используйте рекурсивный CTE, чтобы объединить достаточно строк, чтобы они были больше, чем вы хотите. Затем выберите то, что вы делали раньше.

declare
    @desired int = 5,
    @actual int = (select count(*) from persons);

with

    persons as (

        select    personId,
                  lastName,
                  batch = 0
        from      Persons

        union all
        select    personId,
                  lastName,
                  batch = batch + 1
        from      persons
        where     (batch + 1) * @actual < @desired

    )

    select    
    top (@desired) personId, lastName
    from           persons
    order by       newid()
1 голос
/ 09 мая 2019

Как уже упоминалось.Вместо этого вы можете использовать таблицу подсчета и затем получить случайные строки;

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)))N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3, N N4) --Repeat for more
SELECT TOP 500 YT.*
FROM Tally T
     CROSS JOIN YourTable YT
ORDER BY NEWID();
0 голосов
/ 22 мая 2019

Я добавил временную таблицу результатов, перебрал запрос и поместил результаты в временную таблицу.

declare  @results table(
SSN varchar(10),
Cusip   varchar(10),
...
EndBillingDate  varchar(10))

DECLARE @cnt INT = 0;

WHILE @cnt < @trades
BEGIN
INSERT INTO @results 
   Select   ...

 set @cnt = @cnt + 10
END

select * from @results
0 голосов
/ 09 мая 2019

Я думал о том, как бы вы решили эту проблему, не упорядочивая все записи, особенно несколько раз.

Один из способов - генерировать случайные числа и использовать их для поиска значений в ваших данных:

with n as (
      select rand(checksum(newid())) as r, 1 as n
      union all
      select rand(checksum(newid())) as r, n + 1
      from n
      where n < 10
     ),
     tt as (
      select t.*, lag(tile_end, 1, 0) over (order by tile_end) as tile_start
      from (select t.*, row_number() over (order by newid()) * 1.0 / count(*) over () as tile_end
            from t
           ) t
     )
select tt.*, n.r, (select count(*) from n)
from n left join
     tt
     on n.r >= tt.tile_start and n.r < tt.tile_end;

Здесь - это дБ <> скрипка.row_number() не нужно использовать order by newid().Он может быть упорядочен по ключу с индексом, что делает этот компонент намного более эффективным.

Для более чем 100 строк вам потребуется OPTION (MAXRECURSION 0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...