子查询百分比中有多行

时间:2017-10-12 20:30:30

标签: sql postgresql

SELECT 
    status, date(time), 
    round((SELECT count(*) 
           FROM log 
           WHERE status NOT LIKE '200 OK'
           GROUP BY date(time) 
           ORDER BY date(time)) /
          (SELECT count(*) 
           FROM log 
           GROUP BY date(time) 
           ORDER BY date(time))) * 100 AS percent
FROM 
    log
GROUP BY 
    date(time), status, percent
ORDER BY 
    date(time);

我已经为它编写了代码,但没有回复,我使用的是postgreSQL。 我想要的最后一件事就是找到THE ERROR PERCENTAGE STATUS(参见状态colounm,其中有200 Ok或未找到)。每天都有。

FOR EG-- 2016/07/22 - 1.5%错误

P.S数据库真的很大,有不同的状态和日期,我希望结果日期明智 在上面的代码中,我试图找到每天的(未发现状态/总状态)

2 个答案:

答案 0 :(得分:0)

将子查询中的日期与外部日期(它们应该相同)进行比较,或者您将计算每个日期。

答案 1 :(得分:0)

现有查询的问题:

  • 到目前为止你解决它的方式需要将表“log”扫描3次,从而导致巨大的性能成本
  • 在这里&gt;&gt; WHERE status NOT LIKE '200 OK'&lt;&lt;你看起来确切的值匹配“200 OK”而不是模式匹配,所以你可以使用 LIKE 删除并使用 NOT()之类的&gt;&gt;这样的WHERE NOT status = '200 OK'&lt;&gt; 运算符:WHERE status <> '200 OK'
  • 为了从较低的数字中划分较高的数字,您需要将整数转换为数字

对于后一个简单的例子:

SELECT 1 / 10;          -- results to 0
SELECT 1::numeric / 10; -- results to 0.10000000000000000000

<强>解决方案

要解决所有提到并改进查询并获得预期结果(如果我确实理解了预期结果)那么使用WINDOW函数,这可以通过查询解决,简单如下:

-- The query
SELECT  date(time),
        round(
            (count(1) FILTER (WHERE NOT status = '200 OK'))::numeric * 100 / count(1),
            1
        ) AS errors_rate
FROM    log
GROUP BY 1
ORDER BY 1;

-- Should return something like this:

 time       | errors_rate
------------+------------
 2016-07-05 |        1.2
 2016-07-06 |        1.3
 2016-07-07 |        1.5
...

一些有用的读物​​:

PG Docs: Aggregate Expressions
PG Docs: Window functions
"The FILTER clause in Postgres 9.4" by Anderson Dias