postgresql:每个IN子句的限制
这将整个查询的结果限制为1。相反,我希望为(1,2,3,4,5)中的postgresql:每个IN子句的限制,sql,postgresql,Sql,Postgresql,这将整个查询的结果限制为1。相反,我希望为(1,2,3,4,5)中的parents.id下的每个父项返回一个子项,因此我希望查询返回5 换句话说,每个家长都有多个孩子,我想为每个家长返回一个最年长的孩子 无论如何,这是可以做到的吗?也许可以尝试另一种方法 SELECT children.* FROM children JOIN parents ON (children.parent_id = parents.id) WHERE parents.id IN (1,2,3,4,5) ORDER BY
parents.id下的每个父项返回一个子项,因此我希望查询返回5
换句话说,每个家长都有多个孩子,我想为每个家长返回一个最年长的孩子
无论如何,这是可以做到的吗?也许可以尝试另一种方法
SELECT children.*
FROM
children
JOIN parents ON (children.parent_id = parents.id)
WHERE
parents.id IN (1,2,3,4,5)
ORDER BY children.age DESC
LIMIT 1
正如前面所说的,这取决于要提取的单个子级。从示例查询中,根本不需要父表(因为不需要任何列)
应采取以下措施:
SELECT min(children.parent_id),parent_id,min(child),max(children.age)
FROM
parents left join children
on parents.id=children.parent_id
WHERE
parents.id IN ('1','2','3','4','5')
group by parent_id
通过更改窗口函数中的
order By子句,您可以控制如果有多个子项,则返回哪个子项。在这种情况下,我选择的是最年轻的(按年龄排序
)
似乎您对SQL还不熟悉,因此为了了解window函数(row_number()over(…)
)的用法,您可能需要自己运行内部select,看看会发生什么
如果您简化了实际语句,并且确实需要表parents
中的列,则可以将内部查询与parents
表连接起来:
select id,
parent_id,
age,
... other columns ...
from (
select id,
parent_id,
age,
... other columns ...,
row_number() over (partition by parent_id order by age) as rn
from children
where parent_id in (1,2,3,4,5)
) as ch
where rn = 1
order by age;
使用Postgres的distinct on操作符可以实现同样的效果,这实际上可能更快 如果您有多个必须返回的子项?或者是随机的?什么数据类型是
parents.id
?你不应该拿苹果和桔子作比较<代码>'1'是字符串值,但1
是数字。如果id
定义为整数,则应将其与数字进行比较,而不是与字符串进行比较。已修复。这是一个模拟sql查询,所以犯了一个错误。每个父项都有多个子项,我想每个父项返回一个子项。Hey Fabrizo,你能帮我理解你的查询是如何工作的吗。我对min(children.parent_id)、parent_id、min(child)有点困惑。我编辑了我的问题,要求略有不同。现在您使用group by
确实满足了每个家长只返回一个孩子的要求,但返回的年龄不一定属于该孩子。感谢您的详细回复。我想知道这种类型的查询会很慢吗?如果每个家长都有数千个孩子,而我们每个家长需要50个孩子,那该怎么办?@如果表的索引正确,校友们应该可以正常工作distinct on
通常要快一点,但速度不是很大。但找到答案的唯一方法是测试它并检查执行计划。
select p.*, -- all columns from the parents table
ch.* -- all columns from the children table
from parents p
join (
select id,
parent_id,
age,
... other columns ...,
row_number() over (partition by parent_id order by age) as rn
from children
) as ch on ch.parent_id = p.id and ch.rn = 1
where p.id in (1,2,3,4,5)
order by ch.age;