2012-01-16 202 views
4

我需要编写一个查询,该查询从表中返回聚合和非聚合数据。返回聚合和非聚合结果的SQL查询

下面的例子,应该有助于澄清我正在尝试做什么。我有以下(简化)表如下:

CREATE TABLE course_group_def (
      id  PRIMARY SERIAL KEY, 
      name  TEXT NOT NULL 
     ); 

CREATE TABLE student (
      id  PRIMARY SERIAL KEY, 
      grp_id INTEGER REFERENCES course_group_def(id) ON UPDATE CASCADE, 
      name  TEXT NOT NULL, 
      weight float NOT NULL, 
      height float NOT NULL 
     ); 

为了论证,让我们假设每个学生属于一个和唯一的课程组。我想编写一个查询,将返回设置这样的结果:

student.name,student.weight,weight_apgaw,weight_apgh

其中:

weight_apgaw:是重量个别学生,表示为他/她所属课程组的平均重量的百分比。

weight_apgh: 是学生个人的重量,表示为他/她所属的课程群的平均高度与

我不知道(以及一些想法)有关百分比如何去写这样的查询。我的方法是写两个查询,并以某种方式做了两个表之间的查询 - 但这样的做法似乎是荒谬的和低效的最好的。

有人可以请建议我如何正确编写这样的SQL函数吗?理想情况下,这应该是数据库不可知的。但是,我使用的是PostgreSQL 8.4,所以如果我必须在SQL风格之间进行选择,则优先。

+0

weight_apgh - 个人** **重量表示为平均百分比**高度**? – 2012-01-16 10:16:30

回答

3

沿着这些路线查询应该让你开始:

select s.name 
    , s.weight 
    , ((s.weight/st.avgweight) * 100) as weight_apgaw 
    , ((s.height/st.avgheight) * 100) as weight_aphei 
from student s 
join (
    select grp_id 
     , avg(weight) as avgweight 
     , avg(height) as avgheight 
    from student 
    group by grp_id 
    ) st on s.grp_id = st.grp_id 
7

您需要使用window functions - 像这样:

select name, 
     weight, 
     height, 
     100 * weight/avg(weight) over (partition by grp_id) weight_apgaw, 
     100 * weight/avg(height) over (partition by grp_id) weight_apgh 
from student 
+2

+1 - 我只看到这种类型的答案OVER和OVER;) – MatBailie 2012-01-16 10:26:27