Leave Histograms (Leave Pattern) generation in SQL - mysql

In the Data shown,we need to do a continuous pattern check of Leaves,
for eg:
CASE
WHEN count("Leaves") BETWEEN 1 AND 2 THEN '1-2'
WHEN count("Leaves") BETWEEN 3 AND 5 THEN '3-5'
WHEN count("Leaves") >5 THEN '>5'
ELSE 'Above 5' END AS "Leave Occurence",
On Jan 1st and 2nd employee has taken 2 leaves togather which belongs to
'1-2'Bucket,
similarly 8,9,10,11th JAN it is contineous for 4 Days hence in '3-4'Bucket
and contineously more than 5 Leaves belongs to [<5]Bucket
Now we need the count of each Bucket for Month wise.
Here 1-2Bucket is 2
3-4Bucket is 1
<5 Bucket is also 1
We used this code ,but it gives the SUM,But not checking the contineous pattern
Year Month Leaves
2011 1-Jan 1
2-Jan 1
3-Jan 0
4-Jan 0
5-Jan 0
6-Jan 0
7-Jan 0
8-Jan 1
9-Jan 1
10-Jan 1
11-Jan 1
12-Jan 0
13-Jan 0
14-Jan 0
15-Jan 1
16-Jan 1
17-Jan 1
18-Jan 1
19-Jan 1
20-Jan 1
21-Jan 0
22-Jan 0
23-Jan 1
24-Jan 1

You can identify each group of leaves by counting the number of non-leaves before it. Then you have aggregation:
select min(date), max(date), count(*) as numdays
from (select t.*,
(select count(*)
from t t2
where t2.date <= t.date and t2.leave = 0
) as grp
from t
where t.leave = 1
) t
group by grp;
You can then format the results however you like. This gives you one row per continuous "leave" period.

Related

How to use count in sql based on a IF condition

From this table
groupId
flag
flagValue
1
0
500
2
0
100
1
1
10
2
1
50
3
0
100
1
1
200
3
1
1000
2
1
50
I need this result
groupId
flag1
flag0
valFlag1
valFlag0
totalFlags
1
2
1
210
500
3
2
2
1
100
100
3
3
1
1
1000
100
2
where
flag1 is number of times flag is 1 for a particular group
flag0 is number of times flag is 0 for a particular group
valFlag1 is sum of flagVal when flag is 1
valFlag0 is sum of flagVal when flag is 0
totalFlags is sum of total flags associated with a group
I am stuck as to how to actually count values based on an IF condition.
Anyhelp is appreciated. Thanks.
I have used a table named group_table with your values
Try using this:
SELECT
g.`groupId`,
SUM(g.`flag`=1 ) AS flag1,
SUM(g.`flag`=0) AS flag0,
SUM(CASE WHEN g.`flag`=1 THEN g.`flagValue` ELSE 0 END) AS valFalg1,
SUM(CASE WHEN g.`flag`=0 THEN g.`flagValue` ELSE 0 END) AS valFalg0,
COUNT(*) AS totalFlags
FROM
`group_table` g
GROUP BY g.`groupId`
If you have to use the IF,
SELECT
g.`groupId`,
IF(g.`flag`=1,1,0 ) AS flag1,
IF(g.`flag`=0,1,0) AS flag0,
SUM(IF(g.`flag`=1,g.`flagValue`,0 )) AS valFalg1,
SUM(IF(g.`flag`=0,g.`flagValue`,0 )) AS valFalg0,
COUNT(*) AS totalFlags
FROM
`group_table` g
GROUP BY g.`groupId`, flag1, flag0
They'll produce the same result

MySQL query to get item counts per month - displayed in row for each item

I have MySQL table like this (there will be more items in real scenario):
ID
item
date
1
a
2021-04-01
2
a
2021-04-05
3
a
2021-05-07
4
b
2021-07-09
And I want to create a table (the result will be displayed in HTML table) where each unique item name will have one row and also counts of the item for every month of whole year. So the result for the case above will look like:
item
m1
m2
m3
m4
m5
m6
m7
m8
m9
m10
m11
m12
a
0
0
0
2
1
0
0
0
0
0
0
0
b
0
0
0
0
0
0
1
0
0
0
0
0
I would be able to do that by 2 separate SELECT queries where the second one would probably be in the for loop, but I can't figure out the way how to do that in one SELECT or one multiselect query, if that is even possible.
I got only that far, then got stucked:
SELECT MONTH(date) as m, COUNT(item) as c
FROM itemtable
WHERE YEAR(date)=YEAR(CURRENT_DATE()) AND item="a"
GROUP BY MONTH(date)
It's a pivot operation. In MySQL I usually do it via conditional aggregation:
SELECT item,
SUM(CASE WHEN MONTH(date) = 1 THEN 1 ELSE 0 END) as m1,
SUM(CASE WHEN MONTH(date) = 2 THEN 1 ELSE 0 END) as m2,
...
SUM(CASE WHEN MONTH(date) = 12 THEN 1 ELSE 0 END) as m12
FROM itemtable
WHERE date BETWEEN '2021-01-01' and '2021-12-31'
GROUP BY item
To see how it works, remove the SUM/GROUP BY and look at the raw CASE WHEN - it splits the data across 12 columns in a diagonal, and then the sum/group squishes it to one row:
A A A B C
B -> B ->
C C
I agree with strawberry's observation that this is often best handled in the app code rather than the DB, but as the data is fixed at "month 1" thru "month 12" it does make it relatively easier to do in the DB

Count and Percentage of records in range of values

I have a table with columns
TicketID - ID of the ticket
AssignedTo - UserID of person to whom ticket is assigned
CreatedTime - Time when Ticket is received
HandleTime - Time when Ticket is picked up for handling
FinishTime - Time when Ticket is finished handling
I need to retrieve the following data grouped to individual AssignedTo ID:
AssignedTo
Picking Rate in the following ranges(both % and count)
<1 minutes
1-2 minutes
2-5 minutes
Closing Rate in the following ranges(both % and count)
same ranges as above
Total Tickets
I have come up with a initial query as
SELECT
User,
sum(case when PickupTime <=1 then 1 else 0 end) as range1,
sum(case when PickupTime <=2 then 1 else 0 end) as range2,
...
FROM
(SELECT
((HandleTime - CreatedTime)/60000) as PickupTime,
((FinishTime - CreatedTime)/60000) as CompletedTime,
AssignedTo as User
FROM
TicketTable
)T
GROUP BY
User
Here I am able to get only the Pickup range counts.I still need Pickup range percentages and also Closing range counts and percentages.How do I get them?
EDIT:
Let us consider a sample dataset and only two ranges <=1 and >1 and also consider time as minutes directly here whereas in original table its stored as timestamp.
TicketID | AssignedTo | CreatedTime | HandleTime | FinishTime
1 001 2 3 3
2 001 4 6 8
3 002 1 2 3
In the above table User 001 is assigned a total of 2 tickets and User 002 is assigned a total of 1 ticket.
The PickupTime and CompletedTime for the tickets are
TicketID | PickupTime | CompletedTime
1 1 1
2 2 4
3 1 2
So for User-001 out of the two tickets assigned to him, he has picked 1 ticket within 1 minute range and 1 greater than 1 minute range.So percentage of tickets within 1 minute range is 50% and over 1 minute range is 50% for him.Same applies with regards to CompletedTime and also to the User-002 too.
So the final result what i want is.
AssignedTo | Pickup_range1_count | Pickup_range2_count | Pickup_range1_percentage |
001 1 1 0.5
002 1 0 1
Pickup_range2_percentage | Complete_range1_count | Complete_range2_count |
0.5 1 1
0 0 1
Complete_range1_percentage | Complete_range2_percentage
0.5 0.5
0 1
According to your example you already almost got it. All you need is the ratio of the individual sums and the total sum (or the count would have done it to). Something like
SELECT AssignedTo,
sum(1) AllCount,
sum(CASE
WHEN HandleTime - CreatedTime <= 1
THEN 1
ELSE 0
END) Range1PickupCount,
sum(CASE
WHEN HandleTime - CreatedTime > 1
THEN 1
ELSE 0
END) Range2PickupCount,
...
sum(CASE
WHEN HandleTime - CreatedTime <= 1
THEN 1
ELSE 0
END) / sum(1) * 100 Range1PickupPercentage,
sum(CASE
WHEN HandleTime - CreatedTime > 1
THEN 1
ELSE 0
END) / sum(1) * 100 Range2PickupPercentage,
...
FROM Tickets
GROUP BY AssignedTo;
should be a valid demonstration and something you can continue upon.
(Disclaimer: Not tested at all, as no DDL and DML was provided.)

mysql Table Sum of Positive and Negative Numbers

I have a column which has positive & negative numbers. Is it possible to have sum of all the positive numbers in Col1, negative numbers in Col2 and (Col1 - Col2) in Col3. Then sort by the last Col.
Current table New Table
ID Score ID Pos Neg Diff
1 3 3 5 0 5
1 1 1 4 1 3
1 -1 2 2 1 1
2 1
2 -1
2 1
3 3
3 1
3 1
This gives me the total but i would like to list the Pos and Neg numbers as well.
SELECT ID, SUM(Score) as total FROM results
GROUP BY ID ORDER BY total DESC
Just use a standard pivot query with separate conditional aggregations for the positive and negative numbers.
SELECT
ID,
SUM(CASE WHEN Score >= 0 THEN Score ELSE 0 END) AS Pos,
SUM(CASE WHEN Score < 0 THEN -1*Score ELSE 0 END) AS Neg,
SUM(Score) AS Diff
FROM results
GROUP BY ID
ORDER BY ID
Demo

mysql compare 2 rows same table

I am trying to compare 2 rows and display the same ones.I did browse but was not able to find the right solution.
Table A
Count status Division
20 A 1
30 B 2
10 c 1
12 z 1
From the above table I want to display whose division is same.
Count status Division
20 A 1
10 c 1
12 z 1
Try this
Select * from TableA
Group By Division
Having Count(*) > 1
Select * from TableA
Group By Division
having Count(*) = 1
Here i used case statement , it worked for me
select CompanyCode ,'Commission Pec', Year
,sum(case when CommissionType='Commission Recevied' then JAN else 0 end)/sum(case when CommissionType='Net Payments from WM' and isnull(JAN,0)<>0 then JAN else 1 end)
from Commission_Consolidate
group by CompanyCode,Year
end