Reputation: 1597
I have a rather complex query I need some help with.
basically my table has four fields:
Start Date,
End Date,
Item,
Type
I also need to get the number of days
In order to group them correctly, I need to look at each row, and check if the dates in Start Date Are consecutive, if they are group them, if not it goes into a different group
So if the following dates were in the database:
2013-10-23
2013-10-24
2013-10-28
2013-10-29
Then it should return two rows
2(number of days), 2013-10-23 (startdate) ,2013-10-24 (last consecutive date) , Item, Type
2,2013-10-28,2013-10-29,Item,Type
Then to take things to a more complex level, the grouping needs to be based on the Item and Type also being the same
So that is the following data (StartDate,Item,Type)
2013-10-23,ABC,EFG
2013-10-24,XYZ,WXY
2013-10-28,ABC,EFG
2013-10-29,ABC,EFG
Then the first two would not be grouped because the Item and/or Type are not the same as each other, even though the dates are consecutive.
However the last two would group together because the dates are consecutive and the Item and Type are the same as each other, with wanted result:
number of days startdate last consecutive date Item Type
1 2013-10-23 2013-10-23 ABC EFG
1 2013-10-24 2013-10-24 XYZ WXY
2 2013-10-28 2013-10-29 ABC EFG
I am trying to do this with MySQL, I know I can loop through with the aid of PHP, but it is preferable to do it in MySQL if it is at all possible.
Here is a SQLFiddle with some data in it. http://sqlfiddle.com/#!2/63383/1/0
Upvotes: 0
Views: 233
Reputation: 1597
SELECT DATEDIFF(max(enddate),min(startdate)) + 1 as days, MIN(startdate) as start, MAX(enddate) as end, type, item FROM (
SELECT startdate, enddate,item, type,
@group := @group + 1 - (
type <=> @last_type
AND item <=> @last_item
AND startdate <=> @last_date + INTERVAL 1 DAY
) g,
@last_type := type,
@last_item := item,
@last_date := enddate
FROM productinfo, (
SELECT @group := 0,
@last_type := NULL,
@last_item := NULL,
@last_date := NULL
) init
ORDER BY type, item, startdate
) t GROUP BY g order by start
Upvotes: 0
Reputation: 8123
Try this:
SELECT
DATEDIFF(MAX(startdate), MIN(startdate)) + 1 AS number_of_days,
MIN(startdate) AS startdate,
MAX(startdate) AS last_consecutive_date,
item,
type
FROM (
SELECT @rownum := @rownum + 1 AS row_number,
pi.*
FROM
productinfo pi,
(SELECT @rownum := 0) r
) mydata
GROUP BY item, type, DATE_ADD(startdate, INTERVAL -row_number DAY)
ORDER BY item, type, DATE_ADD(startdate, INTERVAL -row_number DAY)
;
Based on the answer by Andriy M in this thread.
SQLFiddle: SQLFiddle example
Upvotes: 0
Reputation: 125865
SELECT COUNT(*), MIN(startdate), MAX(startdate), item, type FROM (
SELECT startdate, item, type,
@group := @group + 1 - (
type <=> @last_type
AND item <=> @last_item
AND startdate <=> @last_date + INTERVAL 1 DAY
) g,
@last_type := type,
@last_item := item,
@last_date := startdate
FROM productinfo, (
SELECT @group := 0,
@last_type := NULL,
@last_item := NULL,
@last_date := NULL
) init
ORDER BY type, item, startdate
) t GROUP BY g
See it on sqlfiddle.
Upvotes: 2