выбрать произвольное количество строк с N различными значениями в столбце, указанном по внешнему ключу - PullRequest
0 голосов
/ 21 июля 2010

Схема базы данных

CREATE TABLE sites
(
    site_id           INTEGER PRIMARY KEY AUTOINCREMENT,
    netloc            TEXT UNIQUE NOT NULL,
    last_visited      REAL DEFAULT 0,
    crawl_rate        REAL DEFAULT 2,
    crawl_frequency   REAL DEFAULT 604800,
    robots_txt        TEXT DEFAULT 0,
    robots_last_fetch REAL DEFAULT 0,
    allow_all         NUMERIC DEFAULT 0,
    disallow_all      NUMERIC DEFAULT 0,
    active            NUMERIC DEFAULT 0                           
 )

CREATE TABLE urls
(
     url_id       INTEGER PRIMARY KEY AUTOINCREMENT,
     site_id      INTEGER REFERENCES sites (id) NOT NULL,
     scheme       TEXT NOT NULL,
     path         TEXT NOT NULL,
     last_visited REAL DEFAULT 0,
     UNIQUE( site_id, scheme, path)                                   
 )

Как вы, наверное, догадались, это для веб-сканера.

Я хочу получить N сайтов, с которыми связаны просматриваемые URL-адреса, и все вышеупомянутые URL. URL сканируется, если url.last_visited + site.crawl_frequency < current_time, где current_time происходит из функции питонов time.time(). То, что я ищу, вероятно, начнется с чего-то вроде:

SELECT s.*, u.* FROM sites s, urls u ON s.site_id = u.site_id ...

Помимо этого я могу думать только о том, что GROUP BY может сыграть какую-то роль.

1 Ответ

1 голос
/ 21 июля 2010

Вот изящный запрос. Вероятно, есть более умный способ сделать это.

SELECT s.*, u.* 
FROM sites s, urls u ON s.site_id = u.site_id
WHERE s.site_id IN 
    (SELECT DISTINCT site_id
     FROM urls uu INNER JOIN sites ss ON uu.site_id = ss.site_id
     WHERE uu.last_visited + ss.crawl_frequency < current_time 
     ORDER BY ss.site_id
     LIMIT n);

Предполагается, что подзапрос вернет до n различных site_id с хотя бы одним просматриваемым URL. Атрибут ORDER BY не обязательно должен быть site_id. На самом деле ORDER BY совсем не обязательно. Я просто добавил это, потому что согласованность хороша при игре с новым запросом.

Вмещающий запрос возвращает все url s, связанные с n отличными site s, где каждый site имеет хотя бы один сканируемый url. Обратите внимание, что не все возвращенные url обязательно для сканирования; единственная гарантия заключается в том, что по крайней мере один url на site может быть сканирован. Возвращенный site может иметь и не подлежащие сканированию url с.

Если должны быть возвращены только просматриваемые url s, условие синхронизации можно скопировать во вложенном запросе. Я не мог сказать, какое поведение требовалось от вопроса.

P.S. Сейчас я занимаюсь педантизмом, но использование crawl_frequency заставляет меня думать, что его можно назвать crawl_period или crawl_delay вместо

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