从表中获取 N 个元素,同时以一对多关系加入其他表

Fetch N elements from table while joining other table with one-to-many relationship

提问人:Stov 提问时间:11/16/2023 最后编辑:Stov 更新时间:11/16/2023 访问量:70

问:

我有以下数据:

收集:

编号 标签 created_at
1 简历集 #1 2023-01-01
2 名片收藏 #1 2023-02-01
3 简历集 #2 2023-03-01

型:

编号 标签 类型 格式
1 EV5型 简历 21x29.7
2 名片 名片 8.5×5.5

公文:

编号 标签 collection_id model_id
1 约翰·多伊简历 1 1
2 约翰·多里安简历 1 1
3 约翰·特拉沃尔塔 CV 3 1
4 约翰·马尔科维奇名片 2 2

一个集合包含多个文档,一个文档有一个模型。

如何仅获取包含 CV(以及相关 CV)的集合,同时限制返回的集合数量?

(集合的标签只是为了清楚起见,知道文档是否是简历的唯一方法是通过其模型)

使用以下查询:

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;

我得到以下结果,这显然给了我前两行:

编号 标签 created_at 编号 标签 collection_id model_id 编号 标签 类型 格式
1 简历集 #1 2023-01-01 1 约翰·多伊简历 1 1 1 EV5型 简历 21x29.7
1 简历集 #1 2023-01-01 2 约翰·多里安简历 1 1 1 EV5型 简历 21x29.7

相反,我想要的是包含简历的前两个集合,以及有问题的简历:

编号 标签 created_at 编号 标签 collection_id model_id 编号 标签 类型 格式
1 简历集 #1 2023-01-01 1 约翰·多伊简历 1 1 1 EV5型 简历 21x29.7
1 简历集 #1 2023-01-01 2 约翰·多里安简历 1 1 1 EV5型 简历 21x29.7
3 简历集 #2 2023-03-01 3 约翰·特拉沃尔塔 CV 3 1 1 EV5型 简历 21x29.7

SQL Fiddle:http://sqlfiddle.com/#!17/30750

SQL PostgreSQL

评论

0赞 Sahab 11/16/2023
只需从您的查询中删除“仅获取前 2 行;”,如果这不是您想要的,请多说一点
0赞 Stov 11/16/2023
我编辑了我的第一条消息和预期的输出,我希望现在更清楚了

答:

0赞 RCoupy 11/16/2023 #1

@SelVazi的回复实际上会列出你的前两个集合,我的会显示每个集合,考虑检查他的。

根据您的评论进行编辑:

select c.*, d.*, m.*
from document d
inner join collection c on c.id = d.collection_id
inner join model m on m.id = d.model_id and m.type = 'cv'

它将返回模型类型为“cv”的每个集合和文档

评论

0赞 Stov 11/16/2023
感谢您的回复。我已经尝试过了,但它没有给出预期的结果。在您的查询中,该子句将返回 2 个集合,无论它们是否包含 CV。fetch first 2 rows
0赞 RCoupy 11/16/2023
我根据您的评论编辑了我的答案,希望对您有所帮助。
0赞 SelVazi 11/16/2023 #2

我们可以使用窗口函数来限制应该选择的集合数量dense_rank()

select *
from (
  select *, dense_rank() over (order by c.id) as rnk
  from collection c
  join document d on d.collection_id = c.id
  join model m on m.id = d.model_id and m.type = 'cv'
) as s
where rnk <= 2

在这里,您可以获得少于两个不同collection_id的结果。但可能每collection_id不止一个。

在这里演示

评论

0赞 Stov 11/16/2023
感谢您的回复。我已经尝试过了,但它没有给出预期的结果。在您的查询中,该子句将返回 2 个集合,无论它们是否包含 CV。fetch first 2 rows
0赞 Stov 11/16/2023
我编辑了我的第一条消息和预期的输出,我希望现在更清楚了。
1赞 Stov 11/16/2023
这正是我想要的!谢谢。
1赞 Stov 11/16/2023
作为记录,在发布我的并得到答案后,我也在 SO 上发现了这个问题:stackoverflow.com/questions/77044872/......
0赞 Sahab 11/16/2023 #3

希望下面的查询可以提供帮助

select *
from collection
join document on document.collection_id = collection.id and collection.id in(1,3) 
join model on document.model_id = model.id
where model.type = 'cv';