patternsqlMinor
Finding contiguous ranges in grouped data
Viewed 0 times
findingrangesgroupedcontiguousdata
Problem
I have a table with the following structure:
and with data:
I wish to group the data based on
The results should look like:
I went through several posts on this topic but was not able to tweak them to fit my data.
Any help would be appreciated.
CREATE TABLE `Rings` (
ID_RingType CHAR(2),
Number MEDIUMINT UNSIGNED,
ID_User INT(11)
);and with data:
INSERT INTO `Rings` VALUES
('AA',1,1),
('AA',2,1),
('AA',3,1),
('AA',11,1),
('AA',12,1),
('AA',13,1),
('AA',14,1),
('AA',15,1),
('AB',16,1),
('AB',17,1),
('AB',18,1),
('AB',19,1),
('AB',20,2),
('AB',21,2),
('AB',22,2);I wish to group the data based on
ID_User and ID_RingType and for each contiguous range of numbers list the MIN and MAX.The results should look like:
ID_User | ID_RingType | MIN | MAX
1 | 'AA' | 1 | 3
1 | 'AA' | 11 | 15
1 | 'AB' | 16 | 19
2 | 'AB' | 20 | 22I went through several posts on this topic but was not able to tweak them to fit my data.
Any help would be appreciated.
Solution
Since MySQL doesn't support
Sample Data
Query
Output
ROW_NUMBER(), You can use a variable to create a group like this.Sample Data
CREATE TABLE `Rings` (
ID_RingType CHAR(2),
Number MEDIUMINT UNSIGNED,
ID_User INT(11)
);
INSERT INTO `Rings` VALUES
('AA',1,1),
('AA',2,1),
('AA',3,1),
('AA',11,1),
('AA',12,1),
('AA',13,1),
('AA',14,1),
('AA',15,1),
('AB',16,1),
('AB',17,1),
('AB',18,1),
('AB',19,1),
('AB',20,2),
('AB',21,2),
('AB',22,2);Query
SET @grp = 0;
SET @preNum = 0;
SELECT ID_User,ID_RingType,MIN(Number),MAX(Number) FROM
(
SELECT
ID_RingType,
ID_User,
Number,
@grp := CASE WHEN Number = @preNum + 1 THEN @grp ELSE @grp + 1 END grp,
@preNum := Number
FROM `Rings`
ORDER BY ID_RingType,ID_User,Number
)T
GROUP BY ID_RingType,ID_User,grpOutput
ID_User | ID_RingType | MIN | MAX
1 | 'AA' | 1 | 3
1 | 'AA' | 11 | 15
1 | 'AB' | 16 | 19
2 | 'AB' | 20 | 22Code Snippets
CREATE TABLE `Rings` (
ID_RingType CHAR(2),
Number MEDIUMINT UNSIGNED,
ID_User INT(11)
);
INSERT INTO `Rings` VALUES
('AA',1,1),
('AA',2,1),
('AA',3,1),
('AA',11,1),
('AA',12,1),
('AA',13,1),
('AA',14,1),
('AA',15,1),
('AB',16,1),
('AB',17,1),
('AB',18,1),
('AB',19,1),
('AB',20,2),
('AB',21,2),
('AB',22,2);SET @grp = 0;
SET @preNum = 0;
SELECT ID_User,ID_RingType,MIN(Number),MAX(Number) FROM
(
SELECT
ID_RingType,
ID_User,
Number,
@grp := CASE WHEN Number = @preNum + 1 THEN @grp ELSE @grp + 1 END grp,
@preNum := Number
FROM `Rings`
ORDER BY ID_RingType,ID_User,Number
)T
GROUP BY ID_RingType,ID_User,grpID_User | ID_RingType | MIN | MAX
1 | 'AA' | 1 | 3
1 | 'AA' | 11 | 15
1 | 'AB' | 16 | 19
2 | 'AB' | 20 | 22Context
StackExchange Database Administrators Q#110916, answer score: 6
Revisions (0)
No revisions yet.