मुझे संदेह है कि उन्हें कुछ हद तक अनुकूलित किया जा सकता है लेकिन इन प्रश्नों से आपको वह परिणाम मिलना चाहिए जो आप चाहते हैं। वे वही पहले 3 CTE साझा करते हैं जो diff_max
. उत्पन्न करते हैं प्रत्येक data_max
. के लिए मान . पहली क्वेरी में हम बस उस मान में बदलाव की तलाश करते हैं (NULL
. से) एक मूल्य के लिए, या मूल्य में कमी) आउटपुट पंक्तियों को उत्पन्न करने के लिए। दूसरी क्वेरी की चौथी और पांचवीं सीटीई पहली क्वेरी के समान हैं, लेकिन हम एक RANK
जोड़ते हैं diff_max
. तक मान हैं, इसलिए हम JOIN
. कर सकते हैं date_diff_from
. का न्यूनतम मान (इसकी संबद्ध तिथि के साथ) और date_diff_to
6वें सीटीई से मान (जो आपके अन्य प्रश्न
)।
प्रश्न 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