2015-03-14 13 views
0

Я генерирую тестовые данные для новой базы данных, и у меня возникают проблемы с заполнением одного из полей внешнего ключа. Мне нужно создать относительно большое количество (1000) записей в таблице (SurveyResponses), который имеет внешний ключ к таблице с только 6 записей (Surveys)Случайное заполнение внешнего ключа в наборе выборки данных

база данных уже имеет Schools таблицу, которая имеет несколько тысяч записей. Для аргументов ради позволяет сказать, что это выглядит как этот

Schools 
+----+-------------+ 
| Id | School Name | 
+----+-------------+ 
| 1 | PS 1  | 
| 2 | PS 2  | 
| 3 | PS 3  | 
| 4 | PS 4  | 
| 5 | PS 5  | 
+----+-------------+ 

я создаю новую Survey таблицу. Он будет иметь только около 3 рядов.

Survey 
+----+-------------+ 
| Id | Col2  | 
+----+-------------+ 
| 1 | 2014 Survey | 
| 2 | 2015 Survey | 
| 3 | 2016 Survey | 
+----+-------------+ 

SurveyResponses просто связывает школу с опросом.

Survey Responses 
+----+----------+----------+ 
| Id | SchoolId | SurveyId | 
+----+----------+----------+ 
| 1 |  1 |  1 | 
| 2 |  2 |  2 | 
| 3 |  3 |  1 | 
| 4 |  4 |  3 | 
| 5 |  5 |  2 | 
+----+----------+----------+ 

Наполнение SurveyId поля является то, что дает мне больше всего хлопот. Я могу случайным образом выбрать 1000 школ, но я не понял способ генерации 1000 случайных SurveyIds. Я пытался избежать цикла while, но, возможно, это единственный вариант?

Я использую генератор данных SQL Red Gate для генерации некоторых моих тестовых данных, но в этом случае мне бы очень хотелось понять, как это можно сделать с помощью raw SQL.

ответ

0

Вот один из способов, с помощью связанного подзапроса, чтобы получить случайный опрос, связанный с каждой школы:

select s.schoolid, 
     (select top 1 surveyid 
     from surveys 
     order by newid() 
     ) as surveyid 
from schools s; 

Примечание: Это не похоже на работу. Here - это скрипт SQL, показывающий неработоспособность. Я очень удивлен, что это не работает, потому что newid() должен быть

EDIT:

Если вы знаете, идентификаторы обследования не имеют пробелы и начать с 1, вы можете сделать:

select 1 + abs(checksum(newid()) % 3) as surveyid 

Я действительно проверял, что это работает.

EDIT II:

Это, как представляется, чрезмерно агрессивная оптимизация (на мой взгляд). Корреляция запроса, похоже, устраняет проблему. Так, что-то, как это должно работать:

select s.schoolid, 
     (select top 1 surveyid 
     from surveys s2 
     where s2.surveyid = s.schoolid or s2.surveyid <> s.schoolid -- nonsensical condition to prevent over optimization 
     order by newid() 
     ) as surveyid 
from schools s; 

Here является SQL Скрипки демонстрирует это.

+0

Я пробовал это, но все опросы были одинаковыми в результате – pnewhook

+0

@pnewhook. , , Это довольно странно. Я предлагаю другое решение, которое я считаю гораздо менее изящным. –

+0

@GordonLinoff У меня очень похожий вопрос и я не хочу публиковать новый вопрос. Q) Из двух таблиц с PK, отношениями FK **, как я могу просто выбрать верхнюю пятерку из справочной таблицы BedSizeTable и заполнить король/королева/отдельный текст во вторичном «HotelRoomsTable»? ** Я бы хотел превратите это в proc proc, если это возможно. – aggie