Oracle SQL中的查询复杂

时间:2019-05-11 00:44:20

标签: sql oracle oracle11g

我有以下表格及其字段

enter image description here

他们问我一个看起来很复杂的查询,我已经走了两天并尝试了一些事情,它说:

  

对于“艺术体操”的不同方式,希望获得女运动员,奖牌获得者(金,银或铜牌)的平均年龄。分析结果字段的可能内容,以便仅返回期望值,即使对于查询显示的记录集没有任何特定值的数据也是如此。具体来说,我们想显示运动员的性别指标,获得的奖牌以及这些运动员的平均年龄。通过从系统日期(SYSDATE)中减去运动员的出生日期,再减去365,可以计算出年龄。为了避免显示小数,请截断(TRUNC)年龄的计算结果。按运动员的平均年龄对结果进行排序。

好吧,我现在有这个:

select person.gender,score.score
from person,athlete,score,competition,sport
where person.idperson = athlete.idathlete    and
athlete.idathlete=  score.idathlete  and
competition.idsport = sport.idsport and
person.gender='F' and competition.idsport=18 and score.score in 
('Gold','Silver','Bronze')
group by 
person.gender,
score.score;

我知道了

enter image description here

通过添加person.birthdate字段,而不是保留18个获得奖牌的人中的18条记录,我将获得更多记录。

除此之外,我仍然必须使用SYSDATE和TRUNC绘制平均年龄,这是我尝试过的很多方法,但我没有得到。

enter image description here

我觉得这很复杂,或者我对这么多的旋转感到有些饱和,我需要一些帮助。

1 个答案:

答案 0 :(得分:1)

阅读所获得的任务,看来您已经很接近解决方案了。查看以下查询及其说明,注意与查询的区别,看看是否有帮助。

select p.gender,
       ((sysdate - p.birthday) / 365) age,
       s.score
from person p join athlete a on a.idathlete = p.idperson       
              left join score s on s.idathlete = a.idathlete
              left join competition c on c.idcompetition = s.idcompetition
where p.gender = 'F'
  and s.score in ('Gold', 'Silver', 'Bronze')
  and c.idsport = 18
order by age;
  • 减去两个日期时,结果是天数。将其除以365,您大概会得到年数(因为每年有365天,这当然是为了简单起见,因为并非所有年份都有那么多天(提示:leap年))。结果通常是一个十进制数字,例如23.912874918724。为了避免这种情况,系统要求您删除小数,因此-使用TRUNC并获得23作为结果
  • 尽管数据模型包含5个表,但您不必在查询中使用所有表。也许最好的方法是逐步进行。第一个是简单地选择所有女运动员并计算其年龄:

    select p.gender,
           ((sysdate - p.birthday) / 365 age
    from person p
    where p.gender = 'F'
    

    请注意,我已经使用了表别名-我建议您也使用它们,因为它们会使查询更易于阅读(表名可能具有很长的名称,对您没有帮助可读性)。另外,始终使用表别名来避免混淆(哪个列属于哪个表)

  • 对结果满意后,移至另一张表-athletescore表的联接机制一样包含...好吧,得分。请注意,我在score表中使用了外部加入,因为并非所有运动员都获得了奖牌。我认为这就是您所要完成的任务:

      

    ...即使查询显示的记录集没有任何特定值的数据。

  • 建议作为开发人员的我们使用显式表联接,使您可以查看与过滤器分开的所有联接(应属于WHERE子句)。所以:

    NO : from person p, athlete a
         where a.idathlete = p.idperson
           and p.gender = 'F'
    
    YES: from person p join athlete a on a.idathlete = p.idperson
         where p.gender = 'F'
    
  • 然后移到另一个桌子,依此类推。

  • 经常进行测试-不要跳过任何步骤。仅当您确定上一步的结果正确无误时,才移至另一步,因为在大多数情况下,它不会自动修复自身。