SQL: выбрать случайную строку из таблицы, где идентификатор строки отсутствует в другой таблице? - PullRequest
1 голос
/ 26 марта 2010

Я искал быстрые способы выбора случайной строки из таблицы и нашел следующий сайт: http://74.125.77.132/search?q=cache:http://jan.kneschke.de/projects/mysql/order-by-rand/&hl=en&strip=1

Что я хочу сделать, это выбрать случайный URL из моей таблицы 'urls', которого у меня нет в другой таблице 'urlinfo'. Используемый мной сейчас запрос выбирает случайный URL из 'urls', но я нужно изменить его так, чтобы он возвращал только случайный URL, которого нет в таблице 'urlinfo'.

Вот запрос:

SELECT url 
FROM urls JOIN (SELECT CEIL(RAND() * (SELECT MAX(urlid)
                                     FROM urls
                                     )
                           ) AS urlid 
               ) AS r2 USING(urlid);

И две таблицы:

CREATE TABLE urls (
 urlid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
 url VARCHAR(255) NOT NULL
) ENGINE=INNODB;


CREATE TABLE urlinfo (
 urlid  INT NOT NULL PRIMARY KEY,
 urlinfo VARCHAR(10000),
 FOREIGN KEY (urlid) REFERENCES urls (urlid)
   ) ENGINE=INNODB;

Ответы [ 3 ]

3 голосов
/ 26 марта 2010

Как насчет работы с этим случайным решением:

SELECT TOP 1 * FROM urls
WHERE (SELECT COUNT(*) FROM urlinfo WHERE urlid = urls.urlid) = 0
 ORDER BY NEWID()
1 голос
/ 27 марта 2010

Вы можете использовать where not exists, чтобы исключить строки, которые находятся в другой таблице. Для случайной строки одним из вариантов является order by rand() с limit 1:

SELECT url
FROM urls
WHERE NOT EXISTS (
    SELECT *
    FROM urlinfo ui
    WHERE ui.urlid = urls.urlid
)
ORDER BY RAND()
LIMIT 1
1 голос
/ 26 марта 2010

Сначала необходимо выполнить левое внешнее объединение, чтобы получить набор записей в URL-адресах, которых нет в urlinfo, а затем выбрать случайную запись из этого набора.

SELECT * FROM urls
LEFT OUTER JOIN urlinfo
ON urls.urlid = urlinfo.urlid
WHERE urlinfo.urlid IS null

Теперь выберите случайную строку из этого набора - вы можете сделать что-то вроде

SELECT newUrls.url
FROM (    
      SELECT urls.urlid, urls.url FROM urls
      LEFT OUTER JOIN urlinfo
      ON urls.urlid = urlinfo.urlid
      WHERE urlinfo.urlid IS null
     ) as newUrls
WHERE urls.urlid >= RAND() * (SELECT MAX(urlid) FROM urls) LIMIT 1

Однако это будет работать только в том случае, если URL-адреса в urlinfo примерно случайным образом распределены по диапазону возможных значений.

...