Reputation: 850
I have a table with a following structure and data:
id | type | title
--------------------------
1 | 1 | test 1
2 | 1 | test 2
3 | 2 | test 3
4 | 2 | test 4
5 | 1 | test 5
I need to group neighbor rows with the same type
field values.
So the result should be like:
type |
------
1 |
2 |
1 |
Thanks in advance.
Upvotes: 0
Views: 341
Reputation: 33945
Here's one way - although a solution using variables will scale better...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,type INT NOT NULL
,title VARCHAR(12) NOT NULL
);
INSERT INTO my_table VALUES
(1,1,'test 1'),
(3,1,'test 2'),
(4,2,'test 3'),
(7,2,'test 4'),
(9,1,'test 5');
SELECT * FROM my_table;
+----+------+--------+
| id | type | title |
+----+------+--------+
| 1 | 1 | test 1 |
| 3 | 1 | test 2 |
| 4 | 2 | test 3 |
| 7 | 2 | test 4 |
| 9 | 1 | test 5 |
+----+------+--------+
SELECT a.id start
, MIN(c.id) End
, a.type
FROM
( SELECT x.*,COUNT(*) rank FROM my_table x JOIN my_table y ON y.id <= x.id GROUP BY x.id) a
LEFT
JOIN
( SELECT x.*,COUNT(*) rank FROM my_table x JOIN my_table y ON y.id <= x.id GROUP BY x.id) b
ON b.type = a.type
AND b.rank = a.rank - 1
LEFT
JOIN
( SELECT x.*,COUNT(*) rank FROM my_table x JOIN my_table y ON y.id <= x.id GROUP BY x.id) c
ON c.type = a.type
AND c.rank >= a.rank
LEFT
JOIN
( SELECT x.*,COUNT(*) rank FROM my_table x JOIN my_table y ON y.id <= x.id GROUP BY x.id) d
ON d.type = a.type
AND d.rank = c.rank + 1
WHERE b.id IS NULL
AND c.id IS NOT NULL
AND d.id IS NULL
GROUP
BY a.id;
+-------+------+------+
| start | End | type |
+-------+------+------+
| 1 | 3 | 1 |
| 4 | 7 | 2 |
| 9 | 9 | 1 |
+-------+------+------+
Upvotes: 0
Reputation: 25862
this should do the trick.. using user defined variables.
SELECT
type
FROM(
SELECT
type,
if(@a = type, @b, @b := @b + 1) as grouping_col,
@a := type
FROM testing
JOIN (select @a := 1, @b := 0) as temp
) as t
GROUP BY grouping_col;
SQL FIDDLE to play with
Upvotes: 1