Mysql
 sql >> база данни >  >> RDS >> Mysql

Периоди от време на MySQL заявка и стойност на максималния спад спрямо предходната максимална стойност

Подозирам, че могат да бъдат донякъде оптимизирани, но тези заявки трябва да ви дадат желаните резултати. Те споделят едни и същи първите 3 CTE, които генерират diff_max стойност за всеки data_max . В първата заявка просто търсим промяна в тази стойност (от NULL до стойност или намаляване на стойността), за да генерирате изходните редове. 4-ти и 5-ти CTE на втората заявка са подобни на първата заявка, но добавяме RANK към diff_max стойности, така че можем да JOIN минималната стойност (със свързаната с нея дата) към date_diff_from и date_diff_to стойности от 6-та CTE (което е същото като моя отговор на вашия друг въпрос ).

Въпрос 1:

WITH cte AS (SELECT DATE(`date_time`) AS `date`,
                    `data`,
                    MAX(`data`) OVER (ORDER BY `date_time`) AS `data_max`
             FROM `test`),
cte2 AS (SELECT `date`,
                `data`,
                `data_max`,
                CASE WHEN `data` < `data_max` THEN `data` - `data_max` END AS `data_diff`
         FROM cte),
cte3 AS (SELECT `date`, 
                MIN(`data_diff`) OVER (PARTITION BY `data_max` ORDER BY `date`) AS `diff_max`
         FROM cte2),
cte4 AS (SELECT `date`, `diff_max`, LAG(`diff_max`) OVER (ORDER BY `date`) AS `old_diff_max`
         FROM cte3)
SELECT `date`, `diff_max`
FROM cte4
WHERE `diff_max` < `old_diff_max` OR `old_diff_max` IS NULL AND `diff_max` IS NOT NULL

Изход:

date        diff_max
2017-01-04  -3
2017-01-09  -7
2017-01-11  -10
2017-01-13  -2

Въпрос 2:

WITH cte AS (SELECT DATE(`date_time`) AS `date`,
                    `data`,
                    MAX(`data`) OVER (ORDER BY `date_time`) AS `data_max`
             FROM `test`),
cte2 AS (SELECT `date`,
                `data`,
                `data_max`,
                CASE WHEN `data` < `data_max` THEN `data` - `data_max` END AS `data_diff`
         FROM cte),
cte3 AS (SELECT `data_max`, `date`, 
                MIN(`data_diff`) OVER (PARTITION BY `data_max` ORDER BY date) AS `diff_max`
         FROM cte2),
cte4 AS (SELECT `data_max`, `date`, `diff_max`, 
                LAG(`diff_max`) OVER (ORDER BY `date`) AS `old_diff_max`
         FROM cte3),
cte5 AS (SELECT `date`, `diff_max`, 
                RANK() OVER (PARTITION BY `data_max` ORDER BY `diff_max`) AS `diff_rank`
         FROM cte4
         WHERE `diff_max` < `old_diff_max` OR `old_diff_max` IS NULL AND `diff_max` IS NOT NULL),
cte6 AS (SELECT `data_max`, 
                MIN(CASE WHEN `data_diff` IS NOT NULL THEN date END) AS diff_date_from,
                MAX(CASE WHEN `data_diff` IS NOT NULL THEN date END) AS diff_date_to
         FROM cte2
         GROUP BY `data_max`
         HAVING diff_date_from IS NOT NULL)
SELECT diff_date_from, diff_date_to, `date` AS diff_max_date, `diff_max`
FROM cte6
JOIN cte5 ON cte5.date BETWEEN cte6.diff_date_from AND cte6.diff_date_to
WHERE cte5.diff_rank = 1

Изход:

diff_date_from  diff_date_to    diff_max_date   diff_max
2017-01-04      2017-01-06      2017-01-04      -3
2017-01-09      2017-01-11      2017-01-11      -10
2017-01-13      2017-01-13      2017-01-13      -2

Демо на dbfiddle




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да променя дублиращите се редове на уникални стойности в mysql?

  2. Най-ефективният начин за получаване на броя на редовете в таблицата

  3. MySQL LIKE ограничаване

  4. Android:Използване на SSL/HTTPS за свързване с PHP към база данни и използване на POST/GET

  5. ИНДИЯ, STD Code Finder Script в PHP, MYSQL, JQUERY