Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Periode waktu kueri MySQL dan nilai penurunan maksimum vs nilai maksimum sebelumnya

Saya menduga mereka agak dapat dioptimalkan tetapi kueri ini akan memberi Anda hasil yang Anda inginkan. Mereka berbagi 3 CTE pertama yang sama yang menghasilkan diff_max nilai untuk setiap data_max . Dalam kueri pertama, kami baru saja mencari perubahan dalam nilai itu (dari NULL ke nilai, atau penurunan nilai) untuk menghasilkan baris output. CTE ke-4 dan ke-5 dari kueri kedua mirip dengan kueri pertama, tetapi kami menambahkan RANK ke diff_max nilai, jadi kita bisa JOIN nilai minimum (dengan tanggal yang terkait) ke date_diff_from dan date_diff_to nilai dari CTE ke-6 (yang sama dengan jawaban saya untuk pertanyaan lain ).

Pertanyaan 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

Keluaran:

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

Pertanyaan 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

Keluaran:

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

Demo di 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. Kesalahan MySQL #1071 - Kunci yang ditentukan terlalu panjang; panjang kunci maksimal adalah 767 byte

  2. Simbol yang belum terselesaikan:sql::mysql::get_driver_instance(void)

  3. Buat kesalahan pemicu:sintaks tidak valid

  4. Kueri COUNT yang rumit di MySQL

  5. Permintaan MySQL ke waktu rata-rata