2017-10-12 4 views
1
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 OKまたは見つからないステータスcolounmを参照)を毎日見つけることです。 EG-- 2016年7月22日FORサブクエリで複数の行が表示される

から1.5パーセントERROR

PSデータベース異なるステータスと日付と本当に大きいですが、私が望む結果の日付が賢明 上記のコードでは、私は(NOT検索しようとしています-FOUNDステータス/トータルステータス)

+0

をあなたがしようと...「によって意味ですか* Total Status *がその特定の日であるか、または記録されたデータの全履歴を意味する、毎日の(NOT-FOUNDステータス/トータルステータス)を見つけますか? –

答えて

0

問題:

  • あなたはそれがこれまでここに巨大なパフォーマンスコスト
  • を引き起こして3回スキャンするを「ログ」テーブルを必要と解決してきた道>>WHERE status NOT LIKE '200 OK' < <ような)(NOTあなたが正確な値が一致する "200 OK" ではないパターンマッチを探しているので、あなたが LIKE を使用してドロップして使用することができますいずれか>>WHERE NOT status = '200 OK' OR <>ようなオペレータ:WHERE status <> '200 OK'
  • 小さいから大きい数字を分割するために、あなたは後者の迅速たとえば数値

にあなたの整数をキャストする必要があります。

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

ソリューション

すべての言及を解決し、クエリを改善し、期待される結果を得るためには(期待された結果を正しく理解した場合)、WINDOW funcンこれは、のような単純なクエリで解決することができます。

-- 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

+0

おかげさまで、魅力的に働いています –

0

サブクエリ内の日付と外部の日付とを比較してください(同じである必要があります)。そうでないと、すべての日付がカウントされます。既存のクエリと

関連する問題