Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TSQL Group by Column with Multiple Values

I have a table in SQLServer 2008r2 as below.

example dataset

I want to select all the records where the [Fg] column = 1 that consecutively by [Id] order lead into value 2 for each [T_Id] and [N_Id] combination.

There can be instances where record prior to [Fg] = 2 doesn't = 1

There can be any number of records where the value of [Fg] = 1 but only one record where [Fg] = 2 for each [T_Id] and [N_Id] combination.

So for the example below, I want to select records with [Id]s (4,5) and (7,8,9 )and (19,20).

Any records for [T_Id] 3 and 4 are excluded.

Expected output

Expected output

Example data set

DECLARE @Data TABLE ( Id INT IDENTITY (1,1), T_Id INT, N_Id INT, Fg TINYINT )

INSERT INTO @Data
(T_Id, N_Id, Fg)
VALUES
(1, 2, 0), (1, 2, 1), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 3, 0), (2, 3, 1), 
(2, 3, 1), (2, 3, 2), (3, 4, 0), (3, 4, 0), (3, 4, 0), (3, 4, 2), (4, 5, 0), 
(4, 5, 1), (4, 5, 0), (4, 5, 2), (5, 7, 0), (5, 7, 1), (5, 7, 2) 
like image 272
Mazhar Avatar asked Nov 03 '17 11:11

Mazhar


People also ask

How do I group multiple values in SQL?

Remember this order: SELECT (is used to select data from a database) FROM (clause is used to list the tables) WHERE (clause is used to filter records) GROUP BY (clause can be used in a SELECT statement to collect data across multiple records and group the results by one or more columns)

Can we use GROUP BY with 2 columns in SQL?

Yes, it is possible to use MySQL GROUP BY clause with multiple columns just as we can use MySQL DISTINCT clause.

How does GROUP BY work with multiple columns 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.

Can we use multiple GROUP BY in SQL?

Usage of GROUP BY Multiple Columns The group by clause is most often used along with the aggregate functions like MAX(), MIN(), COUNT(), SUM(), etc to get the summarized data from the table or multiple tables joined together.


1 Answers

It can be done easily using recursive CTE:

WITH DataSource AS
(
    SELECT DS1.*
    FROM @Data DS1
    INNER JOIN @Data DS2
        ON DS1.[T_Id] = DS2.[T_Id]
        AND DS1.[N_Id] = DS2.[N_Id]
        AND DS1.[Id] = DS2.[Id] + 1
        AND DS1.[Fg] = 2
        AND DS2.[Fg] = 1
    UNION ALL
    SELECT DS1.*
    FROM @Data DS1
    INNER JOIN DataSource DS2
        ON DS1.[T_Id] = DS2.[T_Id]
        AND DS1.[N_Id] = DS2.[N_Id]
        AND DS1.[Id] = DS2.[Id] - 1
        AND DS1.[Fg] = 1
)
SELECT *
FROM DataSource
ORDER BY Id

enter image description here

The idea is simple. The first part of the query gets all valid records with fg = 2 - valid means there is record before this one with fg = 1 from the same group.

Then in the recursive part we are getting all records smaller then initial ones, that has fg = 1.

like image 55
gotqn Avatar answered Sep 17 '22 17:09

gotqn