Как я могу получить все столбцы в агрегации временного диапазона?

0

В настоящее время я изо всех сил пытаюсь объединить свои ежедневные данные в других агрегатах времени (недели, месяцы, кварталы и т.д.).

Вот как выглядит мой сырой тип данных:

| date     | traffic_type | visits  |
|----------|--------------|---------|
| 20180101 | 1            | 1221650 |
| 20180101 | 2            | 411424  |
| 20180101 | 4            | 108407  |
| 20180101 | 5            | 298117  |
| 20180101 | 6            | 26806   |
| 20180101 | 7            | 12033   |
| 20180101 | 8            | 80368   |
| 20180101 | 9            | 69544   |
| 20180101 | 10           | 39919   |
| 20180101 | 11           | 26291   |
| 20180102 | 1            | 1218490 |
| 20180102 | 2            | 410965  |
| 20180102 | 4            | 108037  |
| 20180102 | 5            | 297727  |
| 20180102 | 6            | 26719   |
| 20180102 | 7            | 12019   |
| 20180102 | 8            | 80074   |

Во-первых, я хотел бы проверить сумму посещений независимо от traffic_type:

SELECT date, SUM(visits) as visits_per_day
FROM visits_tbl
GROUP BY date

Вот результат:

|    ymd   | visits_per_day |
|:--------:|:--------------:|
| 20180101 |     2294563    |
| 20180102 |     2289145    |
| 20180103 |     2300367    |
| 20180104 |     2310256    |
| 20180105 |     2368098    |
| 20180106 |     2372257    |
| 20180107 |     2373863    |
| 20180108 |     2364236    |

Тем не менее, если я хочу проверить конкретный день, в течение которого visit_per_day был самым высоким для каждой агрегирования времени (например: месяц), я изо всех сил пытаюсь получить правильный вывод.

Вот что я сделал:

SELECT 
   (date div 100) as y_month, MAX(visits_per_day) as max_visit_per_day
FROM
    (SELECT date, SUM(visits) as visits_per_day
    FROM visits_tbl
    GROUP BY date) as t1
GROUP BY
   y_month

И вот вывод моего запроса:

| y_month | max_visit_per_day |
|:-------:|:-----------------:|
|  201801 |      2435845      |
|  201802 |      2519000      |
|  201803 |      2528097      |
|  201804 |      2550645      |

Тем не менее, я не могу знать, что было точным днем, когда visit_per_day был самым высоким.

Желаемый результат:

| y_month | max_visit_per_day |    ymd   |
|:-------:|:-----------------:|:--------:|
|  201801 |      2435845      | 20180130 |
|  201802 |      2519000      | 20180220 |
|  201803 |      2528097      | 20180325 |
|  201804 |      2550645      | 20180406 |

ymd будет представлять день, в течение которого visit_per_day был самым высоким. Эта логика будет использоваться в приборной панели с помощью программирования, чтобы автоматически выбирать агрегацию времени. Может кто-нибудь, пожалуйста, помогите мне?

  • 0
    Есть ли какая-либо причина для создания собственного представления DATE вместо использования типа данных MySQL DATE ? Логика дат - такая боль в шее, чтобы понять, что большинство людей используют встроенные типы данных.
  • 0
    Использование типа даты MySQL сделало бы это возможным. Тогда вы могли бы использовать встроенные функции.
Показать ещё 1 комментарий
Теги:
impala

2 ответа

0
Лучший ответ

Это работа для структурированной части структурированного языка запросов. То есть вы будете писать некоторые подзапросы и рассматривать их как таблицы.

Вы уже знаете, как найти количество посещений в день. Добавьте месяц за каждый день к этому запросу (http://sqlfiddle.com/#!9/a8455e/13/0).

                   SELECT date DIV 100 as month, date, 
                          SUM(visits) as visits
                     FROM visits_tbl
                    GROUP BY date

Затем вам нужно найти наибольшее количество ежедневных посещений в каждом месяце. (http://sqlfiddle.com/#!9/a8455e/12/0)

       SELECT month, MAX(visits) max_daily_visits
         FROM (
                   SELECT date DIV 100 as month, date, 
                          SUM(visits) as visits
                     FROM visits_tbl
                    GROUP BY date
              ) dayvisits
        GROUP BY month

Затем, трюк получает дату, в которой этот максимум произошел в каждом месяце. Для этого требуется соединение. Без обычных табличных выражений (которых не хватает MySQL) вам нужно повторить первый подзапрос. (http://sqlfiddle.com/#!9/a8455e/11/0)

SELECT detail.*
  FROM (
           SELECT month, MAX(visits) max_daily_visits
             FROM (
                       SELECT date DIV 100 as month, date, 
                              SUM(visits) as visits
                         FROM visits_tbl
                        GROUP BY date
                  ) dayvisits
            GROUP BY month
        ) maxvisits
   JOIN (
                       SELECT date DIV 100 as month, date, 
                              SUM(visits) as visits
                         FROM visits_tbl
                        GROUP BY date
        ) detail ON detail.visits = maxvisits.max_daily_visits
                AND detail.month = maxvisits.month

Краткое описание этого довольно сложного запроса помогает объяснить это. Вместо этого подзапроса мы будем использовать мнимую таблицу, называемую dayvisits.

SELECT detail.*
  FROM (
           SELECT month, MAX(visits) max_daily_visits
             FROM dayvisits 
            GROUP BY date DIV 100
        ) maxvisits
   JOIN dayvisits detail ON detail.visits = maxvisits.max_daily_visits
                        AND detail.month = maxvisits.month

Вы ищете экстремальное значение для каждого month в подзапросе. (Это довольно стандартный вид операции SQL.) Для этого вы найдете это значение с запросом MAX()... GROUP BY. Затем вы присоединяете это к самому подзапросу, чтобы найти другие значения, соответствующие крайнему значению.

Если у вас есть общие табличные выражения, запрос будет выглядеть так. Вы можете рассмотреть возможность использования вилки MySQL под названием MariaDB, которая имеет CTE.

WITH dayvisits AS (
       SELECT date DIV 100 as month, date, 
          SUM(visits) as visits
     FROM visits_tbl
    GROUP BY date
) 
SELECT dayvisits.*
  FROM (
           SELECT month, MAX(visits) max_daily_visits
             FROM dayvisits
            GROUP BY month
        ) maxvisits
   JOIN dayvisits ON dayvisits.visits = maxvisits.max_daily_visits
                AND dayvisits.month = maxvisits.month
  • 0
    Обычно я использую импалу, которая поддерживает CTE, и я могу легко достичь своих результатов. Я попробую и сообщу, сработало ли это!
0

[Query Check on MSSQL] быстро и эффективно.


select visit_sum_day_wise.date 
, visit_sum_day_wise.Max_Visits
, visit_sum_day_wise.traffic_type
, LAST_VALUE(visit_sum_day_wise.visits) OVER(PARTITION BY 
visit_sum_day_wise.date  ORDER BY visit_sum_day_wise.date  ROWS BETWEEN 
UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS max_visit_per_day
from (
     select visits_tbl.date , visits_tbl.visits , visits_tbl.traffic_type
     ,max(visits_tbl.visits ) OVER (  PARTITION BY visits_tbl.date   ORDER 
     BY  visits_tbl.date  ROWS BETWEEN UNBOUNDED PRECEDING  AND  0  
     PRECEDING) Max_visits
     from visits_tbl  
     ) as visit_sum_day_wise
where visit_sum_day_wise.visits    = (select max(visits_B.visits )  from 
visits_tbl visits_B where visits_B.Date =  visit_sum_day_wise.date )

введите описание изображения здесь

Ещё вопросы

Сообщество Overcoder
Наверх
Меню