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

时间:2011-06-13 15:16:17

标签: sql sql-server

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

说我有以下表格:

  • 编号
  • 名称
  • ...

儿童

  • 编号
  • 的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

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

非常感谢任何帮助!

5 个答案:

答案 0 :(得分:6)

您将OVERPARTITION BY ParentId一起使用的想法是正确的;但是,不要将其与MIN一起使用,而是使用ROW_NUMBER()来获取整行。这样:

SELECT
    ParentId
    , Id
    , Age
    , ROW_NUMBER() OVER ( PARTITION BY ParentId ORDER BY Age ) AS rn
FROM Child

返回所有孩子,以及一个行号,表示他们在同一父母的孩子中的年龄顺序 ,所以我们只需要过滤:

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

注意当您要求“所有父母及其最小的孩子”时,您可能需要考虑在Parent中使用否匹配Child中的记录 - 我的解决方案以及所有其他记录将不包含有关此类Parent记录的任何信息。

答案 1 :(得分:1)

SELECT   
Parent.Id AS ParentId,
C.Id AS ChildId, 
C.Age AS ChildAge 
FROM Parent, CHILD C
WHERE PARENT.ID = C.ParentId
AND C.AGE = 
(
    SELECT MIN(AGE)
    FROM CHILD
    WHERE ParentId = C.ParentId

)

答案 2 :(得分:1)

SELECT   
    Parent.Id AS ParentId,
    Child.Id  AS ChildId, 
    Child.Age AS ChildAge 
FROM Parent
  JOIN Child 
    ON Parent.Id = Child.ParentId
  JOIN
    ( SELECT ParentId,
             MIN(Age) AS ChildAge
      FROM Child
      GROUP BY ParentId   
    ) AS minCh
    ON Child.ParentId = minCh.ParentId
    AND Child.Age = minCh.ChildAge

答案 3 :(得分:-1)

这个可能有效:

SELECT
ParentID,
ChildId,
ChildAge
FROM
(

SELECT   
Parent.Id AS ParentId,
Child.Id AS ChildId, 
MIN(Child.Age) AS ChildAge,   
Ranking  = ROW_NUMBER() OVER(PARTITION BY  ParentID order by Child.Age asc)  

FROM Parent JOIN Child ON Parent.Id = Child.ParentId
GROUP BY Parent.Id, Child.Id, Child.Age
)A
Where Ranking =1

答案 4 :(得分:-2)

您可以尝试这样的事情:

SELECT parentid, id, age FROM child c
 WHERE age = (SELECT MIN(c2.age) FROM child c2 WHERE c2.parentid = c.parentid);

请注意,您可能会找到每个父母不止一个孩子(如果他们的年龄相同,则年龄最小)。