В настоящее время я изо всех сил пытаюсь объединить свои ежедневные данные в других агрегатах времени (недели, месяцы, кварталы и т.д.).
Вот как выглядит мой сырой тип данных:
| 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 был самым высоким. Эта логика будет использоваться в приборной панели с помощью программирования, чтобы автоматически выбирать агрегацию времени. Может кто-нибудь, пожалуйста, помогите мне?
Это работа для структурированной части структурированного языка запросов. То есть вы будете писать некоторые подзапросы и рассматривать их как таблицы.
Вы уже знаете, как найти количество посещений в день. Добавьте месяц за каждый день к этому запросу (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
[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 )
DATE
вместо использования типа данных MySQLDATE
? Логика дат - такая боль в шее, чтобы понять, что большинство людей используют встроенные типы данных.