Reputation: 119
I have table with data like this
price | date | type |
---|---|---|
1000 | 2021-03-13 | A |
1000 | 2021-03-14 | A |
1000 | 2021-03-15 | A |
1300 | 2021-03-16 | A |
1000 | 2021-03-17 | A |
1300 | 2021-03-18 | A |
1000 | 2021-03-19 | A |
1500 | 2021-03-20 | A |
1500 | 2021-03-21 | A |
1500 | 2021-03-22 | A |
2000 | 2021-03-13 | B |
2000 | 2021-03-14 | B |
2000 | 2021-03-15 | B |
2000 | 2021-03-16 | B |
2000 | 2021-03-17 | B |
I want to query data like this
price | startDate | endDate | type |
---|---|---|---|
1000 | 2021-03-13 | 2021-03-15 | A |
1300 | 2021-03-16 | 2021-03-16 | A |
1000 | 2021-03-17 | 2021-03-17 | A |
1300 | 2021-03-18 | 2021-03-18 | A |
1000 | 2021-03-19 | 2021-03-19 | A |
1500 | 2021-03-20 | 2021-03-22 | A |
2000 | 2021-03-13 | 2021-03-17 | B |
my current sql below but it is not correct at all
SELECT MIN(date) as startDate, MAX(date) as endDate, price, type
FROM prices
GROUP BY type, price
ORDER BY type, MIN(date)
Upvotes: 3
Views: 1283
Reputation: 1758
If not using CTE, you can work the following query:
SELECT w1.price, w1.date, w2.date, w1.type FROM
(
SELECT * FROM mytable t1
WHERE NOT EXISTS (
SELECT 1 FROM mytable t2
WHERE
t1.price = t2.price AND
t1.type = t2.type AND
DATEDIFF(t2.date, t1.date) = -1
)
) w1
INNER JOIN
(
SELECT * FROM mytable t1
WHERE NOT EXISTS (
SELECT 1 FROM mytable t2
WHERE
t1.price = t2.price AND
t1.type = t2.type AND
DATEDIFF(t2.date, t1.date) = +1
)
) w2
ON
w1.price = w2.price AND
w1.type = w2.type AND
w1.date <= w2.date AND
NOT EXISTS (
SELECT * FROM mytable t1
WHERE NOT EXISTS (
SELECT 1 FROM mytable t2
WHERE
t1.price = t2.price AND
t1.type = t2.type AND
DATEDIFF(t2.date, t1.date) = +1
)
AND
w1.price = t1.price AND
w1.type = t1.type AND
w1.date <= t1.date AND t1.date < w2.date
)
Upvotes: 0
Reputation: 522762
This is a gaps and islands problem, and one simple way to handle it uses the difference in row numbers method. Assuming you are using MySQL 8+, the following should work:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY type ORDER BY date) rn1,
ROW_NUMBER() OVER (PARTITION BY type, price ORDER BY date) rn2
FROM prices
)
SELECT price, MIN(date) AS startDate, MAX(date) AS endDate, type
FROM cte
GROUP BY price, type, rn1 - rn2
ORDER BY type, startDate;
Upvotes: 2
Reputation: 14
SELECT MIN(date) as startDate, MAX(date) as endDate, price, type
FROM prices
GROUP BY type, price
ORDER BY MIN(date) ASC
This query might work in arranging data in ascending order of date
Upvotes: -1