【问题标题】:How to write a PostgreSQL query to get average of child rows in same table?如何编写 PostgreSQL 查询来获取同一张表中子行的平均值?
【发布时间】:2018-10-23 02:17:00
【问题描述】:

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

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

请看下图了解我的表格

我当前的查询

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

【问题讨论】:

  • 数据的顺序对您来说重要吗?
  • 此处展示表格数据时,请尽量减少图片本身的文字材料。两个表格之间的段落应以文本形式呈现;这是因为图像中的文本与剪贴板、搜索引擎和屏幕阅读器不兼容,因此志愿者更难提供帮助。

标签: sql postgresql


【解决方案1】:

这样做,可能对你有帮助

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

【讨论】:

  • 谢谢伙计。它运行完美,运行迅速,虽然我做了一些修改,但 isnull 在 postgres sql 中不可用
  • 按照MSSQL Server写就行了
【解决方案2】:

这是另一种方式:

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

【讨论】:

  • 谢谢。此查询运行良好,但执行时间稍长。
【解决方案3】:

你似乎想要:

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;

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 2021-03-01
    • 2020-07-05
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多