【发布时间】:2019-06-05 17:19:58
【问题描述】:
我有两个表:任务和页面。第一页有一个列多次引用第二个表,称为 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。提前感谢您的帮助。
【问题讨论】:
-
嗨。这还不清楚。 “搜索表”和“最后使用 WHERE 子句过滤”到底是什么意思?此外,还不清楚您所指的“结果表”(某些子选择?某些 FROM 子句的结果?)和“过滤结果”。请阅读minimal reproducible example 并采取行动。包括你可以做的部分的代码。
-
抱歉,为了清楚起见,我现在添加了完整的 SQL 查询以及实际和所需的输出。
-
这样更好。但是 MCVE 包含我们可以剪切、粘贴和运行的代码,包括 DDL 和(小)输入。另外:你还不清楚。什么表是“WHERE 子句之前的连接表”,“LIMIT 和 OFFSET 起作用”是什么意思?请清楚地识别特定的子表达式。您的段落以“我确实得到了结果,但是”开头也没有意义。例如,什么是“试图寻找”?再次,讨论清楚识别的子表达式的值。 (并且最好通过提供适用于零件的代码来演示。)并且“搜索结果表”仍然没有任何意义。等等。
-
PS 您没有根据输入中出现的行清楚地描述输出中应该出现的行。 PS如果你想限制匹配个任务,为什么要限制一个不匹配个任务表呢? PS 如果您希望 DBMS 从给定的子表达式值重复返回页面,那么您需要在每次请求新页面时重新计算该值。
标签: sql postgresql left-join limit offset