Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to GROUP BY with an exception?

Tags:

Here is my simplied code:

SELECT 
   a.user_id as User_ID,
   min(b.a_day) as Date_from,
   max(b.a_day) as Date_to,
   c.code as ID 
FROM a, b, c 
WHERE 
   a_day > (day, -15, getdate())
GROUP BY 
   a.user_id,
   c.code

Query gives the following output:

User ID date_from   date_to     id    
1234567 2016-06-13  2016-06-13  B
1234567 2016-06-17  2016-06-17  A
12345672016-06-18  2016-06-18   A
1234567 2016-06-19  2016-06-19  A
1234567 2016-06-20  2016-06-20  A
1234567 2016-06-21  2016-06-21  C
1234567 2016-06-22  2016-06-22  C
1234567 2016-06-23  2016-06-23  D

I need something like this:

User ID date_from   date_to     id
1234567 2016-06-13  2016-06-13  B
1234567 2016-06-17  2016-06-20  A
1234567 2016-06-21  2016-06-22  C
1234567 2016-06-23  2016-06-23  D

When I use min() and max() function with group by, it aggregates fine for all records but I have to aggregate only dates with the same ID day after day.

Any ideas?

Thanks in advance.

like image 983
aoc24 Avatar asked Sep 14 '16 07:09

aoc24


People also ask

Can you GROUP BY something not selected?

No, you can GROUP BY a column that was not included in the SELECT statement. For example, this query does not list the price column in the SELECT , but it does group the data by that column.

Can we use * in GROUP BY?

You can, but the "GROUP BY" clause is used for grouping together sets of rows, so it does not make sense for your question (or anything that involves a "SELECT *").

Can we use GROUP BY in with clause?

GROUP BY clause is used with the SELECT statement. In the query, GROUP BY clause is placed after the WHERE clause. In the query, GROUP BY clause is placed before ORDER BY clause if used any. In the query , Group BY clause is placed before Having clause .

Can we use GROUP BY without ORDER BY?

The ORDER BY clause is not strictly necessary. It's up to you to decide whether you want the result set ordered. However, given the whole point of GROUP BY , the following is recommended: You probably want the data displayed in the same order as per the GROUP BY clause, to make the grouping more apparent.


1 Answers

You can do it with conditional grouping by using CASE EXPRESSION in the GROUP BY clause :

SELECT 
   a.user_id as User_ID,
   min(b.a_day) as Date_from,
   max(b.a_day) as Date_to,
   c.code as ID 
FROM a, b, c 
WHERE 
   a_day > (day, -15, getdate())
GROUP BY 
   a.user_id,
   c.code,
   CASE WHEN c.code in ('B','D') THEN b.a_day ELSE 1 END

Which will generate this as the GROUP BY clause :

c.code = 'B' -> a.user_id,c.code,b.a_day
c.code <> 'B' -> a.user_id,c.code,1
like image 76
sagi Avatar answered Sep 25 '22 16:09

sagi