Sql 从一个选择中除以两个计数
我有一张这样的桌子:Sql 从一个选择中除以两个计数,sql,postgresql,select,percentage,Sql,Postgresql,Select,Percentage,我有一张这样的桌子: date(timestamp) Error(integer) someOtherColumns WITH CTE AS ( SELECT m --,extract('year' FROM m) AS theyear --,extract('month' FROM m) AS themonth --,extract('day' FROM m) AS theday ,(SE
date(timestamp) Error(integer) someOtherColumns
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
我有一个查询来选择特定日期的所有行:
SELECT * from table
WHERE date::date = '2010-01-17'
现在,我需要计算错误等于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
您可以使用generate_series并从那里获取它 像这样:
date(timestamp) Error(integer) someOtherColumns
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
有关详细信息,请参见:
试试这个
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
这是怎么回事(如果error
只能是1和0):
或者,如果error
可以是任意整数:
select
date,
sum(case when Error > 0 then 1 end)::numeric / count(Error) as "Percentage of failure"
from Table1
group by date
只是因为我已经计算了
而不是0
(假设错误是当error!=0时),并且没有将空值计入帐户(不知道如何处理它)。下面是另一个查询,它将null视为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;
如果error
可以为NULL
,这甚至可以工作
在这个密切相关的问题下还有更多(包括对绩效的影响):计数方法的比较和基准。它仍然给我:错误:语法错误在或接近“WITH”行1:WITH CTEAS@quin61:我不知道您的表和日期字段是什么,可能是一个无效的日期,但该语句在我的计算机上运行良好。顺便说一句,列名不要使用保留字,如
date
。它可能会导致查询中出现一些令人讨厌的错误。error
beNULL
?您是否需要在结果中连续几天没有任何条目的行?仅此而已。谢谢:)@Roman Pekar:如果count(*)为0,这将(或至少应该)以0除法失败…@Quandary well。。不要认为任何SQL查询都会返回count(*)=0:)@Roman Pekar:啊,是的,我的错,你是对的,group by只需省略无活动的天数即可将你保存在那里。@quin61:请务必按照链接获取性能信息count(*)
比count(col)
快一点,而且对空值也是安全的。严格地说,Roman的答案是错误的,只要我们不知道列是否可以为空。