3

我有一张这样的桌子:

date(timestamp) Error(integer)   someOtherColumns

我有一个查询来选择特定日期的所有行:

SELECT * from table
WHERE date::date = '2010-01-17'  

现在我需要计算 Error 等于 0 的所有行(从那天开始),然后除以所有行的计数(从那天开始)。

所以结果应该是这样的

Date(timestamp)      Percentage of failure
2010-01-17           0.30

数据库非常大,数百万行..

如果有人知道如何在更多天里做到这一点,那就太好了——从一天到另一天。

Date(timestamp)      Percentage of failure
2010-01-17           0.30
2010-01-18           0.71
and so on
4

4 回答 4

5

这个呢(如果error只能是 1 和 0):

select
   date,
   sum(Error)::numeric / count(Error) as "Percentage of failure"
from Table1
group by date

或者,如果error可以是任何整数:

select
   date,
   sum(case when Error > 0 then 1 end)::numeric / count(Error) as "Percentage of failure"
from Table1
group by date

只是发现我已经计算过了not 0(假设错误是当错误!= 0 时),并且没有考虑空值(不知道你想如何处理它)。所以这是另一个查询,它将空值视为 0,并以两种相反的方式计算失败百分比:

select
    date,
    round(count(nullif(Error, 0)) / count(*) ::numeric , 2) as "Percentage of failure",
    1- round(count(nullif(Error, 0)) / count(*) ::numeric , 2) as "Percentage of failure2"
from Table1
group by date
order by date;

sql fiddle demo

于 2013-10-21T14:02:11.500 回答
3

尝试这个

select cast(data1.count1 as float)/ cast(data2.count2 as float) 
 from (
select count(*) as count1 from table date::date = '2010-01-17' and Error = 0) data1, 

(select count(*) as count1 from table date::date = '2010-01-17') data2
于 2013-10-21T13:02:26.530 回答
1
SELECT date
     , round(count((error = 0) OR NULL) / count(*)::numeric, 2) AS percent_fail
FROM   tbl
GROUP  BY 1
ORDER  BY 1;

如果可以,这甚至error可以NULL

-> SQLfiddle 演示。

在这个密切相关的问题下还有更多(包括对性能的影响):
Compute percents from SUM() in the same SELECT sql query

在 dba.SE 上计算此相关答案的方法的比较和基准。

于 2013-10-21T17:07:13.310 回答
0

您可以使用 generate_series 并从那里获取它。

像这样:

WITH CTE AS 
(
     SELECT 
         m
        --,extract('year'  FROM m) AS theyear
        --,extract('month' FROM m) AS themonth
        --,extract('day' FROM m) AS theday

        ,(SELECT COUNT(*) AS cnt FROM  table WHERE date::date = m AND Error = 1) AS data1 
        ,(SELECT COUNT(*) AS cnt FROM  table WHERE date::date = m) AS data2 
    FROM  
    (
        SELECT generate_series('2012-04-01'::date, '2016-01-01'::date, interval '1 day') AS m
    ) AS g 
) -- END OF CTE 

SELECT 
      m
     ,COALESCE(data1 * 100.0 / NULLIF(data2, 0.0), 0.0) AS ErrorPercentage
FROM CTE

有关详细信息,请参阅: 如何在 DO 块中执行选择查询?

于 2013-10-21T12:58:40.297 回答