patternsqlMinor
find the beginning and ending values of sequential runs
Viewed 0 times
thevaluessequentialbeginningfindandendingruns
Problem
This article does the inverse of what I need: Find which numbers in [1, 161] are not in the result set?
Given the sample data they used:
this query answers the question, "What are the gaps?":
What I want to know is what are the islands?
I would like to see output like this:
but I can't quite figure out the query to do so. I am using MySQL 5.6.
Anyone have a solution?
Given the sample data they used:
mysql> CREATE TABLE wp_blogs
-> (
-> blog_id INTEGER
-> );
mysql> insert into wp_blogs values(1);
mysql> insert into wp_blogs values(2);
mysql> insert into wp_blogs values(4);
mysql> insert into wp_blogs values(6);
mysql> insert into wp_blogs values(7);
mysql> insert into wp_blogs values(8);
mysql> insert into wp_blogs values(10);this query answers the question, "What are the gaps?":
mysql> SELECT a.blog_id+1 AS start, MIN(b.blog_id) - 1 AS end
-> FROM wp_blogs AS a, wp_blogs AS b
-> WHERE a.blog_id GROUP BY a.blog_id
-> HAVING start < MIN(b.blog_id);
+-------+------+
| start | end |
+-------+------+
| 3 | 3 |
| 5 | 5 |
| 9 | 9 |
+-------+------+What I want to know is what are the islands?
I would like to see output like this:
+-------+------+
| start | end |
+-------+------+
| 1 | 2 |
| 4 | 4 |
| 6 | 8 |
| 10 | 10 |
+-------+------+but I can't quite figure out the query to do so. I am using MySQL 5.6.
Anyone have a solution?
Solution
To keep all the state information with the current row to avoid
having conditions you can so something like: SELECT start, max(end) FROM (
SELECT
CASE WHEN blog_id = @prev + 1 THEN @start:=@start ELSE @start:=blog_id END AS start,
blog_id AS end,
@prev:=blog_id
FROM (SELECT @prev:=NULL, @start:=NULL) AS vars
JOIN wp_blogs
) a
GROUP BY start;
+---------+------------+
| start | max(end) |
|---------+------------|
| 1 | 2 |
| 4 | 4 |
| 6 | 8 |
| 10 | 10 |
+---------+------------+
4 rows in set
Time: 0.003sCode Snippets
SELECT start, max(end) FROM (
SELECT
CASE WHEN blog_id = @prev + 1 THEN @start:=@start ELSE @start:=blog_id END AS start,
blog_id AS end,
@prev:=blog_id
FROM (SELECT @prev:=NULL, @start:=NULL) AS vars
JOIN wp_blogs
) a
GROUP BY start;
+---------+------------+
| start | max(end) |
|---------+------------|
| 1 | 2 |
| 4 | 4 |
| 6 | 8 |
| 10 | 10 |
+---------+------------+
4 rows in set
Time: 0.003sContext
StackExchange Database Administrators Q#138071, answer score: 4
Revisions (0)
No revisions yet.