简体   繁体   English

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

[英]Select MAX value from column and corresponding value from another

This might be a relatively simple question but I am struggling to work it out. 这可能是一个相对简单的问题,但我正在努力解决。 I have three tables all listed below ( owners, pets, petTypes ) and trying to extract the following data all in one query . 我下面列出了三个表( owners, pets, petTypes ),并试图在一个查询中提取以下数据。 The first two are not difficult but the 3rd and 4th is where I am struggling. 前两个并不难,但是第三和第四是我努力的地方。

Table data if you want to replicate: https://pastebin.com/veXHwcMc 如果要复制表数据: https : //pastebin.com/veXHwcMc

The questions: 问题:

  1. Owner Id 拥有者编号

  2. Owner name 所有者名称

  3. Owners oldest pet age 主人最老的宠物年龄
  4. Owners oldest pet type name 主人最老的宠物类型名称
  5. Number of other pets 其他宠物数

What I have tried 我尝试过的

Selecting the oldest age SELECT MAX(age) FROM pets 选择年龄SELECT MAX(age) FROM pets

Joining the tables to show both SELECT pets.ownerId, MAX(pets.age), petTypes.name FROM pets INNER JOIN petTypes ON pets.petTypeId = petTypes.id GROUP BY pets.ownerId; SELECT pets.ownerId, MAX(pets.age), petTypes.name FROM pets INNER JOIN petTypes ON pets.petTypeId = petTypes.id GROUP BY pets.ownerId;表以同时显示SELECT pets.ownerId, MAX(pets.age), petTypes.name FROM pets INNER JOIN petTypes ON pets.petTypeId = petTypes.id GROUP BY pets.ownerId;

But this is wrong. 但这是错误的。 Because they are all showing cat when they should be showing the correct name for the oldest cat. 因为它们都在显示猫的时候应该为最老的猫显示正确的名称。

I cam upon this question: How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL? 我想到了这个问题: 如何在SQL中用另一列选择MAX(列值),DISTINCT来选择行?

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

But the error thrown is ERROR 1054 (42S22): Unknown column 'petTypes.id' in 'on clause' 但是引发的错误是ERROR 1054 (42S22): Unknown column 'petTypes.id' in 'on clause'

Any help please 任何帮助请

表格+数据

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 ;

The derived table OPets gets a count of all the pets by owner less 1 since we know this represents the "other pet" count. 派生表OPets通过所有者减去1得到所有宠物的计数,因为我们知道这代表“其他宠物”计数。 The max pet age is returned via aggregation grouped owner. 宠物的最大年龄可通过汇总分组的所有者返回。 By joining this data set back to the pet set we get only the pets for that owner having the max age. 通过将此数据集重新加入宠物集,我们只能获得拥有最大年龄的那个主人的宠物。 We then join to petType to get the name of that type of pet (or pets if multiple share same max age). 然后,我们加入petType以获取该类型宠物的名称(如果多个宠物共享相同的最大年龄,则为宠物)。

Finally, group by all the fields except the PT.Name, and select the min(PetType.Name). 最后,对除PT.Name以外的所有字段进行分组,然后选择min(PetType.Name)。 That way if multiple animals exist with the same oldest age, we pick the one with TypeName with the earliest name alphabetically. 这样,如果存在多个具有相同最老年龄的动物,我们将按字母顺序从最早的名字中选择具有TypeName的动物。 This approach only works given the data being returned. 仅在返回数据的情况下,此方法才有效。 If a petname, or the petID had to be returned, a different approach would be needed; 如果必须返回宠物名或宠物ID,则需要使用其他方法。 but this was by far the simplest approach given the desired results (columns returned) 但这是迄今为止获得所需结果(返回的列)的最简单方法

The count-1 seems a bit hackish since count(*) returns a count of all pets -1 simply subtracts out the 1 we know we had for the #5 requirement: Number of other pets. count-1似乎有点骇人听闻,因为count(*)返回所有宠物的数量-1只是减去了我们对#5要求拥有的宠物1: 其他宠物的数量。 Even in the case of ties on age this # will be correct. 即使在年龄关系上,这个#也是正确的。 Since count-1 will always be the "other pets" 由于count-1将永远是“其他宠物”

this should work, cant test it, but if owner has two or more pets same age it will show multiple records. 这应该可以,不能测试,但是如果主人有两个或更多相同年龄的宠物,它将显示多个记录。

   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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM