Я хочу обобщить статус http по дате с amazon athena

#sql #amazon-athena

Вопрос:

У меня есть журналы доступа в Афине, как это.

 time                  hostname    user_agent      http_status  col_0    col_1     col_2    col_3
2018-06-01T10:00:00   host01      Mozilla/5.0     200          2018     6         1        10
2019-06-01T10:00:00   host01      Mozilla/5.0     200          2019     6         1        10
2020-06-01T10:00:00   host01      Mozilla/5.0     404          2020     6         1        10
2021-06-08T10:00:00   host01      Mozilla/5.0     404          2021     6         8        10
2021-06-09T10:00:00   host01      Mozilla/5.0     200          2021     6         9        10
2021-06-10T10:00:00   host01      Mozilla/5.0     404          2021     6         10        10
2021-06-10T11:00:00   host01      Mozilla/5.0     503          2021     6         10        11
2021-06-11T10:00:00   host01      Mozilla/5.0     200          2021     6         11        10
2021-06-12T10:00:00   host01      Mozilla/5.0     503          2021     6         12        10
2021-06-13T10:00:00   host01      Mozilla/5.0     200          2021     6         13        10
2021-06-14T10:00:00   host01      Mozilla/5.0     404          2021     6         14        10
2021-06-15T10:00:00   host01      Mozilla/5.0     200          2021     6         15        10
2021-06-15T11:00:00   host01      Mozilla/5.0     503          2021     6         15        11
 

Я хотел бы посчитать статус http по дате.
В это время необходимо отобразить данные за одну неделю с этого момента.

 date        status_40x  status_50x
2021-06-09  0           0
2021-06-10  1           1
2021-06-11  0           0
2021-06-12  0           1
2021-06-13  0           0
2021-06-14  1           0
2021-06-15  0           1
 

Как мне сделать sql-запрос?

Типы такие …

 time (string) 
hostname (string) 
user_agent (string) 
http_status (string) 
col_0 (string)(Partitioned) 
col_1 (string)(Partitioned) 
col_2 (string)(Partitioned) 
col_3 (string)(Partitioned)
 

запрос

 select d.dte, coalesce(status_404, 0), coalesce(status_503, 0)
from (select date '2021-06-09'   n.n * interval '1' day as dte
      from unnest(sequence(0, 6, 1)) as n(n)
     ) d left join
     (select DATE_TRUNC('DAY', cast(from_iso8601_timestamp(time) as date)) as dte, 
             count_if(http_status = '404') AS status_404,
             count_if(http_status = '503') AS status_503
      from access_logs al
      group by dte
     ) al
     on al.dte = d.dte
 

ошибка

 Error running query: SYNTAX_ERROR: line 9:16: Column 'dte' cannot be resolved
 

Ответ №1:

Вы можете сгруппироваться по дате (например, привести свою метку времени к дате) и использовать count_if :

 WITH dataset AS
  (SELECT *
   FROM (VALUES (TIMESTAMP '2018-06-01 10:00:00', 401), 
                (TIMESTAMP '2018-06-01 11:00:00', 400),
                (TIMESTAMP '2018-06-01 10:00:00', 500), 
                (TIMESTAMP '2018-06-02 11:00:00', 400)) AS t (TIME, http_status))

SELECT cast(TIME AS date),
       count_if(http_status BETWEEN 400 AND 499) AS "40x",
       count_if(http_status BETWEEN 500 AND 599) AS "50x"
FROM dataset
GROUP BY cast(TIME AS date)
 

Что дает следующие результаты:

_col0 40x 50x
2018-06-01 2 1
2018-06-02 1 0

Ответ №2:

Если вы хотите заполнить даты, вам нужно их сгенерировать. Я думаю, что вы можете использовать sequence() для этого:

 select d.dte, coalesce(status_40x, 0), coalesce(status_50x, 0)
from (select date '2021-06-09'   n.n * interval '1 day') as dte
      from unnest(sequence(0, 6, 1)) n(n)
     ) d left join
     (select cast(time as date) as dte, 
             count_if(http_status BETWEEN 400 AND 499) AS status_40x,
             count_if(http_status BETWEEN 500 AND 599) AS status_50x
      from access_logs al
      group by dte
     ) al
     on al.dte = d.dte;
 

Комментарии:

1. извините. Я неправильно понял.