如何在不使用嵌套sql查询的情况下获取聚合

时间:2009-12-11 01:51:41

标签: sql postgresql aggregate

我正在编写一个包含备份作业历史记录的Avamar(Postgresql)数据库的自定义报告。我的任务是显示昨晚失败的作业(基于status_code),并在同一行中包括该客户在过去30天内的成功率(作业成功/总作业运行)。

因此整体选择只会选择失败的客户端(status_code不等于30000,这是成功代码)。但是,对于昨晚每个失败的客户,我还需要知道有多少工作成功,以及在过去30天内开始/安排了多少工作。 (时间段部分很简单,所以我没有将其包含在下面的代码中,以保持简单。)

我尝试在不使用嵌套查询的情况下执行此操作,基于Hobodave对this similar question的反馈,但我无法确定它。

在下面的查询中,我收到以下错误: column "v_activities_2.client_name" must appear in the GROUP BY clause or be used in an aggregate function

这是我的(破碎)查询。我知道逻辑是有缺陷的,但是我想知道如何最好地实现这一目标。提前感谢任何指导!

select
  split_part(client_name,'.',1) as client_name,
  bunchofothercolumnns,
  round(
    100.0 * (
      ((sum(CASE WHEN status_code=30000 THEN 1 ELSE 0 END))) /
      ((sum(CASE WHEN type='Scheduled Backup' THEN 1 ELSE 0 END))))
    as percent_total
from v_activities_2
  where
    status_code<>30000
  order by client_name

2 个答案:

答案 0 :(得分:1)

如果SELECT中的列对其执行了聚合函数,则需要定义GROUP BY:

  SELECT SPLIT_PART(t.client_name, '.', 1) AS client_name,
         SUM(CASE WHEN status_code = 30000 THEN 1 ELSE 0 END) as successes
    FROM v_activities_2
GROUP BY SPLIT_PART(t.client_name, '.', 1)
ORDER BY client_name

您希望以下内容如何发挥作用:

      SUM(CASE WHEN status_code = 30000 THEN 1 ELSE 0 END) as successes
 FROM v_activities_2
WHERE status_code <> 30000

您不能指望计算排除的行。

答案 1 :(得分:0)

为什么要避免嵌套查询?

这似乎是最合乎逻辑/最有效的解决方案。

如果你在一次没有sobqueries(只有group by)的情况下执行此操作,你将结束扫描整个表(或连接表) - 这是无效的,因为昨晚只有一些客户端失败。

一般来说,子查询并不是那么糟糕。