【问题标题】:SQL statement : averageSQL 语句:平均
【发布时间】:2019-11-06 10:15:23
【问题描述】:

我的问题:成为第一个爷爷的平均年龄是多少?解决方案应以average_age 的形式给出。一个人成为爷爷的那一天就是他的第一个孙子出生的地方。

关系:

human (name, gender, age) 
parent (ParentName, ChildName) -> is subset of human(name).

表:

我知道爷爷是一个有父母名字和孩子名字的人,也是一个人(父亲)的父母名字,有孩子的孩子(孙子)。现在的问题是如何计算成为爷爷的平均年龄。

到目前为止我得到了什么:

SELECT AVG(age) as average_age
FROM human h JOIN
     parent p
     ON h.name = p.parentname
WHERE h.gender = 'm' AND p.parentname = p.childname AND h.name = p.parentname

预期结果:

average_age : 52

【问题讨论】:

  • 你说的成为 第一 爷爷是什么意思?
  • @GMB 也许是指一个人的第一个孙子的出生年龄?
  • 更新您的问题添加适当的数据样本和预期结果
  • 父亲第一次当爷爷。这只是意味着一个爷爷也可以有更多的孙子,你必须计算他成为爷爷的平均年龄。
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&运行代码;具有期望和实际输出(包括逐字错误消息)的示例输入(作为初始化代码);标签和版本;明确的规范和解释。对于包含最少代码的错误,您可以给出的代码是您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)对于包含 DBMS 和 DDL 的 SQL,其中包括约束、索引和表格初始化。

标签: sql database join


【解决方案1】:

将人们的年龄存储在表中是非常不寻常的,因为这种情况每天都在变化。数据应与出生日期一起存储。

这是一个聚合查询,但您必须多次连接表。要获得祖父母,您需要加入 parents 表。然后需要带入humans进行过滤:

select avg(min_age * 1.0)
from (select min(h_grandparent.age - h.grandchild.age) as min_age
      from parent p join  -- p.parentname is the grandparent
           parent pchild
           on p.childname = pchild.parentname join
           human h_grandparent
           on p.parentname = h_grandparent.name join
           human h_grandchild
           on pchild.childname = h_grandchild.name
      where h_grandparent.gender = 'm'
      group by h_grandparent.name
     ) a

【讨论】:

  • 为什么要把 min_age 乘以 1.0 ?
  • @Lyaso 。 . .您不指定数据库,有些数据库将整数的平均值作为整数。
【解决方案2】:

我会使用exists 条件来解决这个问题,该条件过滤有孙子的人:

select avg(age) avg_age_of_grandpas
from human h
where 
    gender = 'm'
    and exists (
        select 1
        from parent p1
        inner join parent p2 on p2.parentName = p1.childName
        where p1.parentName = h.name
    )

exists 条件确保此人至少有一个孩子和一个孙子。外部查询计算这些人的平均值。鉴于您的表结构中可用的信息,在我看来,这似乎是最合乎逻辑的方法。与joins 不同,使用exists 可以避免当一个人有多个后代时重复记录(并得到错误的平均结果)。


如果你想知道他们第一个孙子出生日期的祖父母的年龄,那就有点复杂了。这应该会让您接近您的预期:

select avg(h.age - g.maxGrandChildAge) avg_age_of_grandpas
from human h
inner join (
    select 
        p1.parentName grandParentName, 
        max(h1.age) maxGrandChildAge
    from parent p1
    inner join parent p2 on p2.parentName = p1.childName
    inner join human h1 on h1.name = p2.childName
) g
on g.grandParentName = h.name

【讨论】:

  • 谢谢,我得到的平均年龄是 70.5,但期望的结果应该是 52。也许他孙辈的年龄对他的平均年龄有影响?
【解决方案3】:

您可以再使用 2 个 joins 并减去最大孙子的年龄:

SELECT AVG(p_age) average_age
FROM
(
    SELECT  h.name, h.age-MAX(h2.age) as p_age
    FROM parent p1 
        LEFT JOIN parent p2 ON P1.childname = P2.parentname
        INNER JOIN human h ON P1.parentname = h.name
        INNER JOIN human h2 ON P2.ChildName = h2.name
    WHERE h.gender = 'm' AND p2.childname IS NOT NULL
    GROUP BY h.name, h.age
)pAges

请考虑该名称不是执行此任务的合适数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多