postgresql:每个IN子句的LIMIT

时间:2014-01-16 06:27:39

标签: sql postgresql

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

这会将整个查询的结果限制为1。相反,我希望在parents.id IN (1,2,3,4,5)下为每个父项返回1个孩子,所以我希望查询返回5。

换句话说,每个父母都有多个孩子,我希望每个父母返回一个最大的孩子

无论如何,这可以做到吗?

2 个答案:

答案 0 :(得分:1)

从您的示例查询中,根本不需要父表(因为您不需要任何列)。

以下应该这样做:

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;

通过更改窗口函数中的order by子句,您可以控制如果有多个,则返回子项。在这种情况下,我选择最年轻的(order by age

看起来你是SQL的新手,所以为了理解窗口函数(row_number() over (...))的使用,你可能想要自己运行内部选择,看看会发生什么。

如果您简化了真实语句,并且确实需要表parents中的列,则可以使用parents表加入内部查询:

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;

使用Postgres'distinct on运算符可以实现相同的效果,这可能实际上更快。

答案 1 :(得分:0)

也许尝试不同的方法?

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

如上所述,它取决于您要提取的单个孩子。