限制和抵消左联接的搜索查询

时间:2019-01-10 19:10:50

标签: sql postgresql left-join limit offset

我有两个表:任务和页面。第一页上有一列多次引用第二张表,称为 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 个任务?

我正在使用PostgreSQL,顺便说一句。预先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您可以将该计数添加到列列表中:

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;