Mysql Query с несколькими подзапросами с группой по отдельному условию

0

Привет, я слабый PHP-разработчик в MySQL. Сложные сложные запросы заставляют мою голову стрелять. Ниже приведена vulnerability таблицы.

+-----------------------------------------------------------------------------------------------+ 
| id | webisite_id | low_count| high_count | medium_count | date_time           |   vul_date    |
+-----------------------------------------------------------------------------------------------+
| 20 | 6           | 1        | 1          | 1            | 2018-07-04 09:14:04 | 2018-02-01    |
| 19 | 6           | 30       | 30         | 30           | 2018-07-04 09:13:38 | 2018-01-30    |   
| 18 | 6           | 1        | 1          | 1            | 2018-07-04 09:13:16 | 2018-01-01    |
+-----------------------------------------------------------------------------------------------+  

Эта таблица представляет количество подсчетов с низким, средним и высоким уровнем уязвимости для каждого веб-сайта в базе данных. Мы можем ввести столько записей для каждого веб-сайта. Но единственная релевантная запись для веб-сайта - это последняя запись в каждом месяце (на основе vul_date).

Здесь мне нужна помощь. Мне нужен запрос, который получает сумму подсчетов с низким, высоким, средним количеством сайтов каждого месяца за последний год, например, если → веб-сайт с id 1 имеет 1, 2, 3, низкий, высокий, средний номер уязвимости, в июне месяце и → то, что с id 2 имеет 7, 8, 9 соответственно, результат должен быть 8 июня 10, 12. И, как и последний год, каждый месяц должен быть получен результат. Если ни одна запись не должна быть 0.

Обратите внимание, что записи должны быть максимальным значением vul_date и если сайт имеет несколько записей на одном и том же vul_date получите последнюю date_time.

Я постарался написать вопрос так же просто. надеюсь, что вопрос будет понят. Пожалуйста помоги мне с этим

Заранее спасибо.

  • 0
    Таким образом, за каждый месяц вы хотите добавить только последние записи на основе столбца vul_date, так что для большинства месяцев это будет всего одна запись, верно? И какой столбец выводит запись месяца date_time или vul_date?
  • 0
    Почему даты в date_time отличаются от vul_date для сайта 6? например, 2018-07-04 09:14:04 | 2018-02-01 |
Показать ещё 1 комментарий
Теги:
subquery

2 ответа

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

Я думаю, что ниже запрос будет работать для вас.

SELECT 
    SUM(low_count),
    SUM(medium_count),
    SUM(high_count),
    MONTH(vul_date)
FROM
    (SELECT 
        low_count, medium_count, high_count, vul_date, date_time
    FROM
        test
    WHERE
        (website_id , vul_date) IN (SELECT website_id, MAX(vul_date)
            FROM test GROUP BY website_id , MONTH(vul_date))) t
WHERE
    date_time IN (SELECT MAX(date_time) FROM test GROUP BY website_id , vul_date)
GROUP BY MONTH(vul_date);

То, что он делает, сначала находит последний месяц входа в мудрый для каждого идентификатора сайта, который является вашим max vul_date.

SELECT website_id, MAX(vul_date)
            FROM test GROUP BY website_id , MONTH(vul_date)

Если для vul_date имеется более одной записи, она использует date_time для выбора максимального значения из них. Наконец, он суммирует всю дату веб-сайта после группировки месяца.

Вы можете изменить указанный выше запрос, чтобы получить значение 0 за те месяцы, в которых нет записей для каких-либо веб-сайтов.

  • 0
    Благодарю. Я почти у цели .. Требуются некоторые собственные настройки. Вы сэкономили мне много времени .. Большое спасибо
  • 0
    Рад помочь :)
0
DROP TABLE IF EXISTS T;
CREATE TABLE T(id INT, website_id INT, low_count INT, high_count INT, medium_count INT, date_time DATETIME, vul_date DATE);
INSERT INTO T VALUES
( 20 , 6 , 1 , 1 , 1,  '2018-07-04 09:14:04' , '2018-02-01'), 
( 19 , 6 , 30, 30, 30, '2018-07-04 09:13:38' , '2018-01-30'), 
( 18 , 6 , 2 , 2 ,2 ,  '2018-07-04 09:13:16' , '2018-01-01'),
( 17 , 6 , 2 , 2 ,2 ,  '2018-07-04 09:12:01' , '2018-01-01'),
( 90 , 1,1,2,3,'2017-07-05 01:00:00',' 2017-07-06'),
( 90 , 2,8,9,10,'2017-07-05 01:00:00',' 2017-07-06');

select coalesce(c.yyyymm,d.yyyymm) yyyymm,
        coalesce(c.lo,0) lo,
        coalesce(c.hi,0) hi,
        coalesce(c.med,0) med 
from
(

SELECT concat(year(a.vul_date),'-',month(a.vul_date)) yyyymm,
        SUM(LOW_COUNT) lo,SUM(HIGH_COUNT) hi,sum(medium_count) med
from
(
select  website_id,date_time,vul_date
from t
where date_time = (select max(date_time) from t t1 where t1.website_id = t.website_id and t1.vul_date = t.vul_date)
) a
join
(select website_id, date_time,vul_date,
          LOW_COUNT,HIGH_COUNT,medium_count
from t) b
on b.website_id = a.website_id and b.date_time = a.date_time
group by concat(year(a.vul_date),'-',month(a.vul_date))
) c
right join 
(select distinct concat(year(dte),'-',month(dte)) yyyymm from dates d
where dte between date_sub(now(), interval 1 year) and now() 
) d on d.yyyymm = c.yyyymm
;  

Sub query a get the vul_date с самым последним значением data_time, которое затем присоединяется, агрегируется, а затем заполняется отсутствующими датами, используя правильное соединение с таблицей даты/календаря. Если у вас нет дат/календаря, это было бы полезно для этого вида упражнений, есть альтернативы, которые вы можете найти в SO.

Результат

+---------+------+------+------+
| yyyymm  | lo   | hi   | med  |
+---------+------+------+------+
| 2017-7  |    9 |   11 |   13 |
| 2017-8  |    0 |    0 |    0 |
| 2017-9  |    0 |    0 |    0 |
| 2017-10 |    0 |    0 |    0 |
| 2017-11 |    0 |    0 |    0 |
| 2017-12 |    0 |    0 |    0 |
| 2018-1  |   32 |   32 |   32 |
| 2018-2  |    1 |    1 |    1 |
| 2018-3  |    0 |    0 |    0 |
| 2018-4  |    0 |    0 |    0 |
| 2018-5  |    0 |    0 |    0 |
| 2018-6  |    0 |    0 |    0 |
| 2018-7  |    0 |    0 |    0 |
+---------+------+------+------+
13 rows in set (0.04 sec)

Ещё вопросы

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