这可能是一个相对简单的问题,但我正在努力解决这个问题。我在下面列出了三个表格(owners, pets, petTypes
)并尝试在一个查询中提取以下数据全部。前两个并不困难,但第三和第四是我在努力的地方。
如果要复制,请使用表格数据:https://pastebin.com/veXHwcMc
问题:
所有者ID
所有者姓名
我尝试了什么
选择最早的年龄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'
请帮助
答案 0 :(得分:0)
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