如何编写PostgreSQL查询以获取同一表中子行的平均值?

时间:2018-10-22 09:21:47

标签: sql postgresql

我正在使用PostgreSQL中的现有表,该表在同一表中具有子行和父行。我不是数据库专家,因此很难编写返回子行平均值并与父行一起显示的查询。

我创建了函数,但是查询需要更长的时间才能执行,因此我需要在不使用函数的情况下编写查询。编写此查询以使其运行更快的最佳方法是什么?

请查看下面的图片以了解我的桌子

Query

我当前的查询

SELECT task_id, tak_or_project_name, 
    case when c.parent_id = 0 Then getProjectScore(task_id, 'score1') ELSE score1   end as score1,
    case when c.parent_id = 0 Then  getProjectScore(task_id, 'score2') ELSE score2  end as score2,
    case when c.parent_id = 0 Then getProjectScore(task_id, 'score3')  ELSE score3  end as score3
FROM tbl_task c

3 个答案:

答案 0 :(得分:2)

只要这样做,可能会对您有帮助

Select a.task_id, a.task_or_project_name, 
    case when a.Parent_id = 0 then isnull(PScore1, Score1) else Score1 end as Score1,
    case when a.Parent_id = 0 then isnull(PScore2, Score2) else Score2 end as Score2,
    case when a.Parent_id = 0 then isnull(PScore3, Score3) else Score3 end as Score3,
    a.Parent_id
    from tbl_task as a
    left join (
        select Parent_id, 
               sum(Score1)/count(score1) as PScore1, 
               sum(Score2)/count(score2) as PScore2, 
               sum(Score3)/count(score3) as PScore3 
        from tbl_task as inner 
        where Parent_Id !=0 
        group by Parent_Id
    ) as parent on a.task_id = parent.Parent_Id

答案 1 :(得分:1)

这是另一种方式:

SELECT
    t1.task_id,
    t1.name,
    COALESCE(ROUND(AVG(t2.score1), 1), 0) AS score1,
    COALESCE(ROUND(AVG(t2.score2), 1), 0) AS score2,
    COALESCE(ROUND(AVG(t2.score3), 1), 0) AS score3,
    t1.parent_id
FROM tbl_task t1
LEFT JOIN tbl_task t2
    ON CASE WHEN t1.parent_id = 0 THEN t1.task_id = t2.parent_id ELSE t1.task_id = t2.task_id END
GROUP BY t1.task_id, t1.name, t1.parent_id
ORDER BY t1.task_id

产生:

| task_id | name                 | score1 | score2 | score3 | parent_id |
| ------- | -------------------- | ------ | ------ | ------ | --------- |
| 1       | Project1             | 18.3   | 13.0   | 25.0   | 0         |
| 2       | task1                | 10.0   | 10.0   | 10.0   | 1         |
| 3       | task2                | 15.0   | 15.0   | 20.0   | 1         |
| 4       | task3                | 30.0   | 14.0   | 45.0   | 1         |
| 5       | Project2             | 16.0   | 23.0   | 54.0   | 0         |
| 6       | task1                | 14.0   | 25.0   | 64.0   | 5         |
| 7       | task2                | 18.0   | 21.0   | 44.0   | 5         |
| 8       | Project3             | 0      | 0      | 0      | 0         |
| 9       | task without project | 15.0   | 14.0   | 19.0   | -1        |

https://www.db-fiddle.com/f/ebmaThfxucoZx7sHx4ukA/0

答案 2 :(得分:0)

您似乎想要:

Select t.task_id, t.task_or_project_name, 
       coalesce(c.score1, t.score1) as score1,
       coalesce(c.score2, t.score2) as score2,
       coalesce(c.score3, t.score3) as score3
       t.Parent_id
from tbl_task t left join
     (select c.Parent_id, 
             avg(c.Score1) as score1,
             avg(c.Score2) as score2, 
             avg(c.Score3) as score3 
      from tbl_task c 
      where c.parent_id <> 0
      group by c.Parent_Id
     ) c
     on t.task_id = c.Parent_Id;