SQL to 'group' certain records - sql

I am not entirely sure if this is possible in SQL (I am by no means an expert).
I have lines of data in TABLEA like below:
I wish to have an SQL output that will 'group' any records together that where Activity!=D. The output results would need look like the table below:
Any 'merged' activities would would be grouped as 'Merged'. In the example, this would be A and B.
I got started
select
cycle_start,
cycle_end,
activity_start,
activity_end,
case when (Activity="D") then "D" else "Merged" end
but then I struggle to get the aggregation correct

Yes, you can do this with a case in the group by:
select cycle_start, cycle_end,
min(activity_start) as activity_start,
max(activity_end) as activity_end,
(case when Activity = 'D' then 'D' else 'Merged' end)
from table t
group by cycle_start, cycle_end,
(case when Activity = 'D' then 'D' else 'Merged' end)

Related

Is there a way to contruct this kind of result using group by in sql?

I have a table which consists of data where in I'm having trouble counting the corresponding rows.
Here is the sample table:
I am expecting an output like this:
You can do conditional aggregation:
select
sum(case when result = 'X' then 1 else 0 end) count_x,
sum(case when result is null then 1 else 0 end) count_blank
from mytable
I assume that by blank you mean null. If not, then you can change the condition in the second sum() from result is null to result = ''.
If you are running MySQL, this can be shortened a little:
select
sum(result = 'X') count_x,
sum(result is null) count_blank
from mytable

Partition table based on joined table

We have 2 Tables Lead and Task.
One lead can have multiple Tasks.
We want to determine if a Lead has a Task who's description contains String 'x'.
If the Lead has the String the it should belong to group1 if it doesn't to group2.
Then we want to count the leads per group and week.
The problem we have is that if a Lead has several tasks and one of them has string 'x' in its description and the others don't it is counted in both groups.
We would need something that resembles a break; statement in the IFF clause of the subquery, so that if the first condition = Contain string x is satisfied the other tasks are not counted anymore.
How would we achieve that?
So far we have the following statement:
--SQL:
SELECT LeadDate, GROUP, COUNT(LEAD_ID_T1)
FROM LEAD Lead INNER JOIN
(SELECT DISTINCT LEAD.ID AS LEAD_ID_T1,
IFF(CONTAINS(Task.DESCRIPTION,
'x'),
'GROUP1',
'GROUP2') AS GROUP
FROM TASK Task
RIGHT JOIN LEAD ON TASK.WHO_ID = LEAD.ID
) T1 ON T1.LEAD_ID_T1 = LEAD.ID
GROUP BY LeadDate,GROUP;
Code breaks because it can not aggregate the measures.
Really thankful for any input. This has been bothering me for a few days now.
I am thinking EXISTS with a CASE expression:
select l.*,
(case when exists (select 1
from task t
where t.who_id = l.id and
t.description like '%x%'
)
then 'GROUP1' else 'GROUP2'
end) as the_group
from lead l;
You can also try something like this, CASE with 1 and 0 then take the SUM
SELECT LeadDate,
sum(CASE When t.description like '%x%'then 1 else 0 end) as Group1,
sum(CASE When t.description like '%x%'then 0 else 1 end) as Group2
FROM TASK t
RIGHT JOIN LEAD l ON t.WHO_ID = l.ID
GROUP BY LeadDate;

How to create an alias that counts Ws, Ls, and Ds to create a record

I have a table with sports results with a column labeled 'Result' where the values in that column are either W, L, or D. I would like to create an alias column that will quickly count the Ws, Ls, and Ds from the whole table in that columns and display it as 'Count W-Count L-Count D'.
I'm very new to SQL and I haven't figured this specific of a request out, nor can I find the correct search terms in Google to discover a video or forum result for the situation I am looking for.
If you want the values in separate columns, use conditional aggregation:
select sum(case when result = 'W' then 1 else 0 end) as w_cnt,
sum(case when result = 'L' then 1 else 0 end) as l_cnt,
sum(case when result = 'T' then 1 else 0 end) as t_cnt
from t;
Best option go for group by
Select result, count(*) from table
where column IN ('W' , 'L' , 'D' )
group by result

Group data by one column and creating a new column based on a rows in each group

I have 'Task' and 'Start time' columns in my data. For each Task, there may be one or more Start times. What I want to do is, categorize each task as an 'X' task if all its Start times are equal and as a 'Y' task if all its Start times are not equal.
This is how the table should look like :
This can be achieved by using a group by and counting the distinct start time and using a case to return X or Y.
Select task,
(case when count(distinct start_time) = 1 then 'X' else 'y' end)
from tasks
group by task;
or this if you want it to look exactly like the picture.
Select tasks.task, tasks.start_time, new.new
from tasks, (Select task,
(case when count(distinct start_time) = 1 then 'X' else 'y' end) as new
from tasks
group by task) as new
where tasks.task = new.task;
You can view my solution here https://paiza.io/projects/Zu7IBFc-5tFBK8xDuf3hPg?language=mysql P.S. I just use Integer instead of date because I didn't feel like dealing with dates lol.
Select task,
(case when count(distinct start_time) = 1 then 'X' else 'y' end)
from tasks
group by task;
With group by task get the value of new_column for each task and then join to the table tasks:
select t.id, t.task, g.new_column
from tasks t inner join (
select
task,
(case when count(distinct starttime) = 1 then 'X' else 'Y' end) new_column
from tasks
group by task
) g on g.task = t.task

Multiple SUM values using WHERE clauses in Oracle

I am writing a SQL statement against an Oracle 10g database. I want to obtain the SUM of a field with three different conditions. Can I do this with one query?
This is pseudo-SQL for what I want:
SELECT SUM(CP) AS CPTotal,
(SUM(CP) FROM tasks WHERE Code='P') AS CPProd,
(SUM(CP) FROM tasks WHERE Code='S') AS CPSupp
FROM tasks;
A conditional SUM() can be had via CASE statements:
SELECT SUM(CP) AS CPTotal,
SUM(CASE WHEN Code = 'P' THEN CP ELSE 0 END) AS CPProd,
SUM(CASE WHEN Code = 'S' THEN CP ELSE 0 END) AS CPSupp
FROM tasks;
The ELSE portion is not needed as NULL results when a value does not match any criteria in a CASE statement, and NULL is ignored on aggregation, but some prefer to include it.
You can use CASE to conditional check for the value of code.
SELECT SUM(CP) AS CPTotal,
SUM(CASE WHEN Code = 'P' THEN CP END) AS CPProd,
SUM(CASE WHEN Code = 'S' THEN CP END) AS CPSupp
FROM tasks