I have the following data:
collection:
id | label | created_at |
---|---|---|
1 | Collection of CVs #1 | 2023-01-01 |
2 | Collection of business cards #1 | 2023-02-01 |
3 | Collection of CVs #2 | 2023-03-01 |
model:
id | label | type | format |
---|---|---|---|
1 | CVs | cv | 21×29.7 |
2 | Business cards | business card | 8.5×5.5 |
document:
id | label | collection_id | model_id |
---|---|---|---|
1 | John Doe CV | 1 | 1 |
2 | John Dorian CV | 1 | 1 |
3 | John Travolta CV | 3 | 1 |
4 | John Malkovich business card | 2 | 2 |
A collection contains multiple documents, and a document has one model.
How do I fetch only collections containing CVs (along with the CVs in question) while limiting the number of collections returned?
(Collections’ labels are only here for clarity, the only way to know if a document is a CV is through its model)
With the following query:
select *
from collection
join document on document.collection_id = collection.id
join model on document.model_id = model.id
where model.type = 'cv'
fetch first 2 rows only;
I get the following result, which obviously gives me the first two rows:
id | label | created_at | id | label | collection_id | model_id | id | label | type | format |
---|---|---|---|---|---|---|---|---|---|---|
1 | Collection of CVs #1 | 2023-01-01 | 1 | John Doe CV | 1 | 1 | 1 | CVs | cv | 21×29.7 |
1 | Collection of CVs #1 | 2023-01-01 | 2 | John Dorian CV | 1 | 1 | 1 | CVs | cv | 21×29.7 |
What I want instead is the first two collections containing CVs, along with the CVs in question:
id | label | created_at | id | label | collection_id | model_id | id | label | type | format |
---|---|---|---|---|---|---|---|---|---|---|
1 | Collection of CVs #1 | 2023-01-01 | 1 | John Doe CV | 1 | 1 | 1 | CVs | cv | 21×29.7 |
1 | Collection of CVs #1 | 2023-01-01 | 2 | John Dorian CV | 1 | 1 | 1 | CVs | cv | 21×29.7 |
3 | Collection of CVs #2 | 2023-03-01 | 3 | John Travolta CV | 3 | 1 | 1 | CVs | cv | 21×29.7 |
SQL Fiddle: http://sqlfiddle.com/#!17/30750
2
Answers
edit based on your comment:
it will return every collections and documents with model type ‘cv’
We can use window function
dense_rank()
to limit number of collection that should be selectedHere, you get results with less than two distinct collection_id. But possibly more than one per collection_id.
Demo here