【问题标题】:more than one row in subquery percentage子查询百分比超过一行
【发布时间】:2017-10-13 18:23:38
【问题描述】:
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。 我想要的最后一件事是找到每天的错误百分比状态(请参阅有 200 确定或未找到的状态列)。

对于 EG-- 2016/07/22 - 1.5% 错误

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

【问题讨论】:

  • 在您的预期结果中,您的意思是指“...尝试查找每天的(未找到状态/总状态)”,总状态适用于那个特定的日子,或者你的意思是记录数据的整个历史?

标签: sql postgresql


【解决方案1】:

现有查询的问题:

  • 到目前为止,您解决它的方式需要扫描表 “log” 3 次,从而导致巨大的性能成本
  • 在这里>>WHERE status NOT LIKE '200 OK' LIKE 删除并使用 NOT() em> 像这样 >> WHERE NOT status = '200 OK' 像这样的运算符: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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2016-07-26
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多