Ограничить и сместить поисковый запрос с левым соединением - PullRequest
0 голосов
/ 10 января 2019

У меня есть две таблицы: задачи и страницы. На первой странице есть столбец, который ссылается на вторую таблицу несколько раз и называется page_number . Я хочу получить все поля первой таблицы и все значения номер страницы для одного и того же tasks.id . Мой запрос для получения этих данных таков:

SELECT
TASKS.ID,TASKS.URL,TASKS.ASSIGNEE,PAGES.TASK_ID,PAGES.PAGE_NUMBER
FROM TASKS
INNER JOIN (SELECT * FROM TASKS ORDER BY TASKS.ID LIMIT ? OFFSET ?)
AS T ON (TASKS.ID=T.ID)
LEFT JOIN PAGES ON (TASKS.ID=PAGES.TASK_ID);

Это работает, и я получаю вывод примерно так:

      id  |          url          | assignee | task_id | page_number
------+-----------------------+----------+---------+-------------
   15 | /vector.pdf           |          |      15 |           1
   15 | /vector.pdf           |          |      15 |           2
   23 | /raster.pdf           |          |      23 |           1
   23 | /raster.pdf           |          |      23 |           2
   23 | /raster.pdf           |          |      23 |           4
 1001 | https://everette.com  |          |    1001 |           1
 1001 | https://everette.com  |          |    1001 |           2
 1002 | https://scarlett.com  |          |    1002 |           1
 1002 | https://scarlett.com  |          |    1002 |           2
 1002 | https://scarlett.com  |          |    1002 |           3
 1002 | https://scarlett.com  |          |    1002 |           4
 1002 | https://scarlett.com  |          |    1002 |           5
 1002 | https://scarlett.com  |          |    1002 |           6
 1002 | https://scarlett.com  |          |    1002 |           7

Но я столкнулся с другими требованиями: мне нужно получить общее количество таблицы TASKS и в том же запросе (для разбивки на страницы во внешнем интерфейсе), и мне нужно иметь возможность искать в результирующей таблице (то есть ищите любую подстроку в таблице). Для поиска по таблице я сделал это:

SELECT 
TASKS.ID,TASKS.URL,TASKS.ASSIGNEE,PAGES.TASK_ID,PAGES.PAGE_NUMBER
FROM TASKS
INNER JOIN (SELECT * FROM TASKS ORDER BY TASKS.ID LIMIT ? OFFSET ?)
AS T ON (TASKS.ID=T.ID)
LEFT JOIN PAGES ON (TASKS.ID=PAGES.TASK_ID)
WHERE TASKS.URL  LIKE ?
OR CAST(TASKS.ID AS TEXT) LIKE ?

Я получаю результаты, но LIMIT и OFFSET работают с объединенной таблицей до предложения WHERE, поэтому я установил LIMIT на что-то вроде 10, а OFFSET на 5, попытался найти запись в первых 5 записях и не получил результаты, потому что соответствующие записи находятся далее в исходной таблице:

SELECT
TASKS.ID,TASKS.URL,TASKS.ASSIGNEE,PAGES.TASK_ID,PAGES.PAGE_NUMBER
FROM TASKS
INNER JOIN (SELECT * FROM TASKS ORDER BY TASKS.ID LIMIT 10 OFFSET 5)
AS T ON (TASKS.ID=T.ID)
LEFT JOIN PAGES ON (TASKS.ID=PAGES.TASK_ID)
WHERE TASKS.URL  LIKE '%everette%'
OR CAST(TASKS.ID AS TEXT) LIKE 99

Фактическая выработка:

 id | url | assignee | task_id | page_number
----+-----+----------+---------+-------------
(0 rows)

Ожидаемый результат:

id  |          url          | assignee | task_id | page_number
------+-----------------------+----------+---------+-------------
1001 | https://everette.com  |          |    1001 |           1
1001 | https://everette.com  |          |    1001 |           2

Как мне структурировать этот запрос, чтобы я получал все записи, которые соответствуют предложению WHERE, получая максимум limit tasks?

Я использую PostgreSQL, кстати. Заранее спасибо за любую помощь.

1 Ответ

0 голосов
/ 10 января 2019

Вы можете добавить это количество в список столбцов:

SELECT ... column list ..., 
       (select count(*) from tasks) as total_task
FROM tasks
  JOIN (SELECT * FROM tasks ORDER BY tasks.id LIMIT ? OFFSET ?) AS T 
    ON tasks.id = t.id
  LEFT JOIN pages ON tasks.id pages.task_id;
...