Возникли проблемы с запросом MySQL для получения случайных комбинаций из 3 таблиц - PullRequest
2 голосов
/ 29 июня 2011

Это был первоначальный вопрос:

Хорошо, вот моя проблема, у меня есть две таблицы, одна названа по имени, а другая по фамилии.Здесь я пытаюсь найти 100 возможных комбинаций из этих имен для тестовых данных.Таблица фамилий содержит 5494 записи в одном столбце, а таблица фамилий содержит 88799 записей в одном столбце.Единственный запрос, который мне удалось составить, который имеет некоторые результаты:

SELECT * FROM
    (SELECT * FROM firstnames ORDER BY rand()) f
    LEFT JOIN
         (SELECT * FROM lastnames 
ORDER BY rand()) l ON 1=1 limit 10;    The problem with this code is

, что он выбирает 1 имя и дает каждую фамилию, которая может пойти с ним.Хотя это и правдоподобно, мне придется установить ограничение в 500000000, чтобы получить все возможные комбинации, не имея только 20 имен (и я бы не хотел убивать мой сервер).Однако мне нужно только 100 случайных поколений записей для тестовых данных, и я не смогу получить это с помощью этого кода.Может ли кто-нибудь дать мне какой-нибудь совет?

  • На этот вопрос уже дан ответ, мне нужен совет по приведенному ниже вопросу.Я просто предоставляю его в качестве фона.

Я хочу присоединить другую таблицу к миксу с именем status.Эта таблица содержит 5 записей в одном столбце, и всякий раз, когда я пытаюсь соединить ее с двумя другими, она заканчивается повторением двух других таблиц так, чтобы теги состояния соответствовали каждой из них.Единственное, с чем я добился небольшого успеха, это:

SELECT *
FROM ( SELECT firstnames FROM firstnames ORDER BY RAND( )  LIMIT 5 ) AS First
JOIN ( SELECT lastnames FROM lastnames ORDER BY RAND( )  LIMIT 5 ) as Last 
JOIN ( SELECT status FROM status ORDER BY RAND( ) LIMIT 1) AS Status ON 1=1;

Хотя имя и фамилия не повторяются в этом запросе, в каждом из них указан только один тег состояния.Ребята, большое спасибо за вашу помощь!

Ответы [ 5 ]

2 голосов
/ 29 июня 2011

Используя переменные MySQL, вы должны быть в состоянии сделать что-то вроде ... Хотя это явно не проверено, это ДОЛЖНО дать вам то, что вы хотите. Вы не можете сделать простое декартово перекрестное объединение, потому что, как вы знаете, оно получит первое имя и объединит со всеми последними именами, а затем с последующим именем со всеми фамилиями ...

В этом запросе используются переменные MySQL. Внутренний запрос (предварительно соответствующие имена и фамилии) предварительно запросит 10 случайных имен (или фамилий). Затем присоедините это к @variable для последовательности имени (@fns) и последовательности фамилии (@lns). Так как обе будут иметь только 10 записей, и каждая из них будет начинаться со своего счетчика в 0, они ОБА приведут к записи с последовательностью от 1 до 10, и, таким образом, JOIN будет находиться в ПОСЛЕДОВАТЕЛЬНОСТИ, где будет иметь место только одна из каждого гарантированного значения. ... vs rand (), который возвращает некоторую дробь с плавающей запятой, где вам никогда не гарантируется, что число из одной таблицы будет совпадать с числом другой таблицы.

select
      First10.FirstName,
      Last10.LastName,
      ( SELECT status FROM status ORDER BY RAND( ) LIMIT 1) AS Status
   from 
      ( select fn.FirstName,
               @fns := @fns + 1 as Sequence
           from
             ( select FirsName,
                  from FirstNames
                  order by rand() 
                  limit 10 ) fn,
             (select @fns := 0 ) vars
      ) First10

      JOIN

      ( select ln.LastName,
               @lns := @lns + 1 as Sequence
           from
              ( select LastName,
                   from LastNames
                   order by rand() 
                   limit 10 ) ln,
              (select @lns := 0 ) vars 
      ) Last10

      ON First10.Sequence = Last10.Sequence
0 голосов
/ 29 июня 2011

Это должно решить проблему статуса:

SELECT
    First.firstnames firstname
    Last.lastnames lastname
    ( SELECT status FROM status ORDER BY RAND() LIMIT 1 ) status
FROM 
    ( SELECT firstnames FROM firstnames ORDER BY RAND()  LIMIT 5 ) First
    JOIN ( SELECT lastnames FROM lastnames ORDER BY RAND()  LIMIT 5 ) Last
0 голосов
/ 29 июня 2011

Как насчет того, чтобы включить его:

SELECT f.name,l.name FROM lastnames l INNER JOIN firstnames f ON 1=1 ORDER BY rand() limit 100;

Внутренние соединения быстрее, чем левые и т.д.?

0 голосов
/ 29 июня 2011

Я понятия не имею, что делает ваша таблица состояния, но это даст вам случайные имена:

select firstnames, lastnames
from (select firstnames from firstnames order by rand() limit 100) fn
cross join (select lastnames from lastnames order by rand() limit 100) ln
order by rand()
limit 100;

Псевдонимы выбора есть, поэтому запрос возвращается в это время - в кресте 10000 строкприсоединиться ... управляемым.Без них было бы миллиарды строк - запрос не вернулся бы с количеством строк

0 голосов
/ 29 июня 2011

Я бы сначала добавил (autunbered) поле id для обеих таблиц.

Тогда я бы написал хранимую процедуру, которая:

  • Создает временную таблицу randomid с 2 полями (firstid, lastid).

  • Вставка 100 строк (или нужного вам числа) со случайными целыми числами в двух полях (от 1 до MAX (firstnames.id) в первое поле и от 1 до MAX (lastnames.id) в второй).

  • Присоединяет таблицы firstnames и lastnames к randomid

  • Удаляет временную таблицу.

...