Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL GROUP BY: intervals in continuity?

The idea is that say you have the following table.

-------------
| oID | Area|
-------------
| 1 | 5     |
| 2 | 2     |
| 3 | 3     |
| 5 | 3     |
| 6 | 4     |
| 7 | 5     |
-------------

If grouping by continuity is possible this pseudo query

SELECT SUM(Area) FROM sample_table GROUP BY CONTINUITY(oID)

would return

-------------
| SUM(Area) |
-------------
|  10       |
|  12       |
-------------

Where the continuity break arises at oID or rather the lack thereof an entry representing oID 4.

Does such functionality exist within the standard functions of Sql?

like image 439
CBusBus Avatar asked Mar 20 '12 12:03

CBusBus


People also ask

Can we use GROUP BY and count together in SQL?

We can use GROUP BY to group together rows that have the same value in the Animal column, while using COUNT() to find out how many ID's we have in each group. It returns a table with three rows (one for each distinct animal).

What does Group_by do in SQL?

The GROUP BY statement groups rows that have the same values into summary rows, like "find the number of customers in each country". The GROUP BY statement is often used with aggregate functions ( COUNT() , MAX() , MIN() , SUM() , AVG() ) to group the result-set by one or more columns.

Can we use ORDER BY and GROUP BY at the same time?

Both GROUP BY and ORDER BY are clauses (or statements) that serve similar functions; that is to sort query results. However, each of these serve very different purposes; so different in fact, that they can be employed separately or together.

Can you GROUP BY multiple things in SQL?

The SQL GROUP BY clause is used along with some aggregate functions to group columns that have the same values in different rows. The group by multiple columns technique is used to retrieve grouped column values from one or more tables of the database by considering more than one column as grouping criteria.


1 Answers

There is no such functionality in "standard functions of SQL", but it is possible to get the desired result set by using some tricks.

With the subquery illustrated below we create a virtual field which you can use to GROUP BY in the outer query. The value of this virtual field is incremented each time when there is a gap in the sequence of oID. This way we create an identifier for each of those "data islands":

SELECT  SUM(Area), COUNT(*) AS Count_Rows
FROM    (
        /* @group_enumerator is incremented each time there is a gap in oIDs continuity */
        SELECT  @group_enumerator := @group_enumerator + (@prev_oID != oID - 1) AS group_enumerator,
                @prev_oID := oID AS prev_oID,
                sample_table.*
        FROM    (
                SELECT  @group_enumerator := 0,
                        @prev_oID := -1
                ) vars,
                sample_table
        /* correct order is very important */
        ORDER BY
                oID
        ) q
GROUP BY
        group_enumerator

Test table and data generation:

CREATE TABLE sample_table (oID INT auto_increment, Area INT, PRIMARY KEY(oID));
INSERT INTO sample_table (oID, Area) VALUES (1,5), (2,2), (3,3), (5,3), (6,4), (7,5);

I need to thank Quassnoi for pointing out this trick in my related question ;-)

UPDATE: added test table and data and fixed duplicate column name in example query.

like image 174
Kaii Avatar answered Nov 14 '22 00:11

Kaii