从列中选择MAX值,从另一个中选择相应的值

时间:2017-11-10 17:23:48

标签: mysql sql greatest-n-per-group

这可能是一个相对简单的问题,但我正在努力解决这个问题。我在下面列出了三个表格(owners, pets, petTypes)并尝试在一个查询中提取以下数据全部。前两个并不困难,但第三和第四是我在努力的地方。

如果要复制,请使用表格数据:https://pastebin.com/veXHwcMc

问题:

  1. 所有者ID

  2. 所有者姓名

  3. 业主年龄最大的宠物年龄
  4. 拥有者最早的宠物类型名称
  5. 其他宠物数量
  6. 我尝试了什么

    选择最早的年龄SELECT MAX(age) FROM pets

    加入表格以显示SELECT pets.ownerId, MAX(pets.age), petTypes.name FROM pets INNER JOIN petTypes ON pets.petTypeId = petTypes.id GROUP BY pets.ownerId;

    但这是错误的。因为当他们应该为最老的猫显示正确的名字时,他们都在展示猫。

    我提出这个问题:How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?

    所以我尝试了:SELECT petTypes.id, petTypes.name FROM petTypes INNER JOIN (SELECT MAX(age) FROM pets GROUP BY ownerId) pets ON petTypes.id = pets.petTypeId;

    但抛出的错误是ERROR 1054 (42S22): Unknown column 'petTypes.id' in 'on clause'

    请帮助

    tables + the data

2 个答案:

答案 0 :(得分:0)

Working demo:

SELECT O.ID, O.FirstName, O.LastName, P.Age, min(PT.Name) as TypeName, OPets.CntOfOtherPets
FROM Owners O
INNER JOIN (SELECT OwnerID, max(Age) MA, count(*)-1 as CntOfOtherPets 
            FROM Pets 
            GROUP BY OwnerID) OPets
 on  OPets.OwnerID = O.ID
INNER JOIN Pets P
 on P.Age = OPets.MA
and P.OwnerID = OPets.OwnerID
INNER JOIN PetTypes PT
 on P.PetTypeID = PT.ID
GROUP BY  O.ID, O.FirstName, O.LastName, P.Age, OPets.CntOfOtherPets ;

派生的表格OPets获得所有者所有宠物的计数减1,因为我们知道这代表了其他宠物"计数。最大宠物年龄通过聚合分组所有者返回。通过将此数据集加回到宠物集中,我们只获得具有最大年龄的所有者的宠物。然后我们加入petType以获取该类型宠物的名称(如果多个共享最大年龄,则为宠物)。

最后,按除PT.Name之外的所有字段进行分组,然后选择min(PetType.Name)。这样,如果存在多个具有相同年龄的动物,我们会按字母顺序选择具有最早名称的TypeName。这种方法仅在返回数据时才有效。如果必须退回宠物名称或petID,则需要采用不同的方法;但这是迄今为止最简单的方法,给出了预期的结果(返回的列)

count-1似乎有点hackish,因为count(*)返回所有宠物的数量-1只是减去我们知道的#5要求的1: 其他的数量 宠物。即使在年龄关系的情况下,这也是正确的#。因为count-1将永远是"其他宠物"

答案 1 :(得分:0)

这应该有效,不能测试,但如果所有者有两个或更多相同年龄的宠物,它将显示多个记录。

   Select ow.Firstname, ow.lastname ,petinfo.Age, petinfo.Name, petcount.TotalPets
    from #owners ow
    join ( Select age, p.petTypeId, p.OwnerID, pt.name From 
               (select max(age) as age, petTypeId, OwnerID 
                from #pets p 
                Group by  OwnerID,petTypeId
                ) p
            Join #petTypes pt on pt.ID = p.petTypeId
           ) petinfo 
           on petinfo.OwnerID = ow.id
    Join (
          Select Count(*) TotalPets, ownerID 
          From #Pets 
          group by OwnerID
          ) petcount
         on petcount.ownerID = ow.ID