2017-06-08 146 views
0

我的SQL很生鏽。我有一個記錄所有HTTP請求及其狀態的表。我所想要做的就是創建一個查詢,其中顯示出狀態=「404 NOT FOUND」每天Postgres:返回百分比的查詢

這裏的結果的百分比是表的樣子

articles=# select * from log limit 1; 

      path    |  ip  | method | status |    time   | id 
-------------------------------+----------------+--------+--------+----------------------------+--------- 
/article/balloon-goons-doomed | 198.51.100.108 | GET | 200 OK |  2016-07-01 06:02:39-05 | 1688046 

我能得到原始計數是這樣的,但不知道如何獲得百分比

SELECT date_trunc('day', time) "day", count(*) as count FROM log WHERE 
status='404 NOT FOUND' group by 1 ORDER BY 1; 

回答

2

你需要的是conditional aggregation

形式的PostgreSQL 9.4,對於它的明確語法(agg_func(...) FILTER (WHERE <predicate>)):

SELECT date_trunc('day', time) "day", 
     COUNT(*) FILTER (WHERE status = '404 NOT FOUND')::NUMERIC 
     /COUNT(*) "not found/total" 
FROM  log 
GROUP BY 1 
ORDER BY 1 

對於早期版本,你可以模擬與CASE表達式(你只需要確保,該CASE表達的THEN分支總是非NULL;離開了ELSE分公司將在所有其他情況下產生NULL S,所以COUNT()不會指望他們):

SELECT date_trunc('day', time) "day", 
     COUNT(CASE WHEN status = '404 NOT FOUND' THEN status END)::NUMERIC 
     /COUNT(*) "not found/total" 
FROM  log 
GROUP BY 1 
ORDER BY 1 
+0

感謝這是最初返回0但工作有輕微變化 SELECT date_trunc('day',time)「day」, ROUND(COUNT(*)FILTER(WHERE status ='404 NOT FOUND'):: NUMERIC /COUNT(*)* 100,2)「404 Percentage」 FROM log GROUP BY 1 ORDER BY 1 – hypnotoad

+0

@hypnotoad是的,OFC:我忘了cast到'numeric'('int/int'是'int' ,對於'0'和'1'之間的值,它將始終爲'0')。如果你想要百分比,'100.0 * COUNT(...)FILTER(...)/ COUNT(...)'也是一個有效的解決方案。 – pozs

0

可以在子查詢中選擇總計數嗎?

SELECT date_trunc('day', time) as day, count(*)/totalCount.count * 100 as percentage 
FROM log, 
(
    SELECT count(*) FROM log 
) totalCount 
WHERE status='404 NOT FOUND' group by 1 ORDER BY 1; 
+0

錯誤:列「totalcount.count」必須出現在GROUP BY子句中或用於聚合函數 – hypnotoad

+0

哦,是的,據我所知count並不需要group by。我認爲你可以通過1 ORDER BY 1'完全刪除該組? –

0

你可以試試這個: 下面的示例查詢將給予總記錄數和也被滿足您的病情記錄的計數。 (這是MYSQL的例子)

SELECT 
((COUNT * 100)/TOTAL_REC_COUNT) AS PERCENT 
FROM 
(
SELECT COUNT(*) as TOTAL_REC_COUNT,SUM(CASE WHEN STATUS='404 NOT FOUND' then 1 ELSE 0 END) AS COUNT 
FROM test.sample_table 
) TMP