聚合函数,用于选择与另一个成功聚合函数对应的列的值匹配

Mat*_*son 6 sql sql-server

对不好的主题感到抱歉.我想不出更好的一个,我赶时间.

说我有以下表格:

  • ID
  • 名称
  • ...

儿童

  • ID
  • 的ParentId
  • 年龄
  • ...

父母和孩子之间存在一对多的关系.

现在我想构建一个返回所有父母及其最小孩子的查询.我希望结果是这样的:

结果

  • Parent.Id
  • Child.Id
  • Child.Age

每个Parent.Id在结果中也应该只有一行.

这是一个解释我想要的图像

http://i.stack.imgur.com/L6PjL.png

这就是我现在所处的位置:

SELECT   
Parent.Id AS ParentId,
Child.Id AS ChildId, 
MIN(Child.Age) AS ChildAge -- OVER (PARTITION BY Parent.Id) AS ChildAge
FROM Parent JOIN Child ON Parent.Id = Child.ParentId
GROUP BY Parent.Id, Child.Id
Run Code Online (Sandbox Code Playgroud)

我想要的是一个聚合函数来放置Child.Id,它将获取对应于MIN(Child.Age)行的Child.Id.我找不到任何这样的东西,我似乎无法模仿这种行为.

任何帮助深表感谢!

Aak*_*shM 6

你使用OVERa的想法PARTITION BY ParentId是正确的方向; 但是,而不是使用它MIN,用它与ROW_NUMBER()得到的整行.这个:

SELECT
    ParentId
    , Id
    , Age
    , ROW_NUMBER() OVER ( PARTITION BY ParentId ORDER BY Age ) AS rn
FROM Child
Run Code Online (Sandbox Code Playgroud)

返回所有子项,以及指示同一父项的子项中的年龄顺序的行号,因此我们只需要过滤:

SELECT ParentId, Id, Age FROM (
    SELECT
        ParentId
        , Id
        , Age
        , ROW_NUMBER() OVER ( PARTITION BY ParentId ORDER BY Age ) AS rn
    FROM Child
) c   -- need to alias the subquery in order to SELECT from it
WHERE rn = 1


ParentId    Id          Age
----------- ----------- -----------
1           11          2
2           13          4
3           15          3
4           19          1
Run Code Online (Sandbox Code Playgroud)

请注意,当你问"所有的父母和他们最小的孩子",你可能要考虑你想要返回什么记录Parent没有在符合条件的记录Child-我的解决方案,与所有其他人一样,将不包括有关此类的任何信息Parent记录.