Reputation: 31
I've got two tables: tasks and pages. The first page has a column that references the second table multiple times, called page_number. I want to get all fields of the first table and all page number values for the same tasks.id. My query for getting this data is as such:
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);
This works, and I get an output like so:
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
But I've come upon other requirements: I need to get a total count of the TASKS table as well in the same query (for pagination in the front-end), and I need to be able to search the resulting table (i.e look for any substring in the table) . To search the table, I did this:
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 ?
I do get results, but LIMIT and OFFSET work on the joined table before the WHERE clause, so I set LIMIT to something like 10 and OFFSET to 5, try to look for a record that's in the first 5 records and get no results because the matching records are further on in the original table:
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
Actual output:
id | url | assignee | task_id | page_number
----+-----+----------+---------+-------------
(0 rows)
Expected Output:
id | url | assignee | task_id | page_number
------+-----------------------+----------+---------+-------------
1001 | https://everette.com | | 1001 | 1
1001 | https://everette.com | | 1001 | 2
How should I structure this query so I get all records that match the WHERE clause, getting at most limit tasks?
I'm using PostgreSQL, btw. Thanks in advance for any help.
Upvotes: 3
Views: 2960
Reputation:
You could add that count to the column list:
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;
Upvotes: 1