Want to calculate leave days month wise in mysql - mysql

Scenario is if Employee apply for leave: From Date is "2016-03-30" and To Date is "2016-04-02" so Output will be "In 3rd month leave days should be 2" and "In 4th month leave days should be 1".
I have Table:
UserID FromDate ToDate LeaveDuration
------------------------------------------------------
0001 20/03/2016 21/03/2016 1
0001 30/03/2016 02/04/2016 2
In 2nd record 2 days should be consider in 3rd month and 1 day should be consider in 4th month.
I tried below query:
select sum(datediff(ToDate,FromDate)) as Total
from wp_ag_assign_leave
where UserId=18
and LeaveType="Carry Forward Leave"
and (EXTRACT(MONTH FROM CURDATE())=EXTRACT(MONTH FROM FromDate)
OR EXTRACT(MONTH FROM CURDATE())=EXTRACT(MONTH FROM ToDate))
Please Help me to solve it

you may want to precise some dates usind e.g date_add but here's what I've done :
select month,
sum(duration) as 'LeaveDays'
from (
select if(month(FromDate)=month(ToDate),month(FromDate),'other') as 'month',
if(month(FromDate)=month(ToDate),datediff(Todate, FromDate),'other') as 'duration'
from wp_ag_assign_leave
UNION
select if(month(FromDate)!=month(ToDate),month(FromDate),'other') as 'month',
if(month(FromDate)!=month(ToDate),datediff(last_day(FromDate),FromDate),'other') as 'duration'
from wp_ag_assign_leave
UNION
select if(month(FromDate)!=month(ToDate),month(ToDate),'other') as 'month',
if(month(FromDate)!=month(ToDate),dateDiff(ToDate,last_day(FromDate)),'other') as 'duration'
from wp_ag_assign_leave
) as parseMonths
where month!='other'
group by month
order by month;
The 3 SELECTin the UNION statement :
- 1 the dates are in the same month, simple difference
- 2 the dates are NOT in the same month : 1st month's part
- 2 the dates are NOT in the same month : 2nd month's part

As per scenario calculate month and year wise leave days
select user_id,ymonth,
sum(duration) as 'LeaveDays'
from (
select user_id,if(EXTRACT(YEAR_MONTH FROM leave_from)=EXTRACT(YEAR_MONTH FROM leave_to),EXTRACT(YEAR_MONTH FROM leave_from),'other') as 'ymonth',
if(EXTRACT(YEAR_MONTH FROM leave_from)=EXTRACT(YEAR_MONTH FROM leave_to),datediff(leave_to, leave_from)+1,'other') as 'duration'
from leave_application
UNION ALL
select user_id, if(EXTRACT(YEAR_MONTH FROM leave_from)!=EXTRACT(YEAR_MONTH FROM leave_to),EXTRACT(YEAR_MONTH FROM leave_from),'other') as 'ymonth',
if(EXTRACT(YEAR_MONTH FROM leave_from)!=EXTRACT(YEAR_MONTH FROM leave_to),datediff(last_day(leave_from),leave_from)+1,'other') as 'duration'
from leave_application
UNION ALL
select user_id, if(EXTRACT(YEAR_MONTH FROM leave_from)!=EXTRACT(YEAR_MONTH FROM leave_to),EXTRACT(YEAR_MONTH FROM leave_to),'other') as 'ymonth',
if(EXTRACT(YEAR_MONTH FROM leave_from)!=EXTRACT(YEAR_MONTH FROM leave_to),dateDiff(leave_to,last_day(leave_from)),'other') as 'duration'
from leave_application
) as parseMonths
where ymonth!='other'
group by ymonth
order by ymonth

Related

Mysql count columns values based on condition

I have a table with columns day, month, year, total_payments. And I have to calculate total_payments according to days, months, years.
How can I calculate values?
I am thinking code like :
select
month, year, sum(total_payments)
from
webassignment.subscription_stats
group by
day;
select
month, year, sum(total_payments)
from
webassignment.subscription_stats
group by
month;
select
month, year, sum(total_payments)
from
webassignment.subscription_stats
group by
year;
but it will not return the correct answers. And I want to calculate total_payments daywise, monthwise, yearwise. Please help me to find values.
Sample input :
Day Month Year Total_payments
10 01 2008 10
10 01 2008 20
11 02 2008 10
10 03 2010 10
Output:
Daywise :
day month year total_payments
-----------------------------
10 01 2008 30
11 02 2008 10
10 03 2010 10
Same for month and yearwise
You can get a summary with Totals by Year, Month and Day using GROUP BY WITH ROLLUP:
SELECT
`Year`,
`Month`,
`Day`,
SUM(`Total_payments`) as `Totals`
FROM `webassignment`.`subscription_stats`
GROUP BY `Year`,`Month`,`Day` WITH ROLLUP;
If you want individual queries for Year, Month and Day:
By Year:
SELECT
`Year`,
SUM(`Total_payments`) as `Totals`
FROM `webassignment`.`subscription_stats`
GROUP BY `Year`
ORDER BY `Year;
By Month:
SELECT
`Year`,
`Month`,
SUM(`Total_payments`) as `Totals`
FROM `webassignment`.`subscription_stats`
WHERE `Year` = 2017
GROUP BY `Year`,`Month`
ORDER BY `Year`,`Month`;
By Day:
SELECT
`Year`,
`Month`,
`Day`,
SUM(`Total_payments`) as `Totals`
FROM `webassignment`.`subscription_stats`
GROUP BY `Year`,`Month`,`Day`
ORDER BY `Year`,`Month`,`Day`;
A way could be the use on an union for show the different result based on different group by level
select day, month,year,sum(total_payments)
from webassignment.subscription_stats group by day, month,year
union
select null, month,year,sum(total_payments)
from webassignment.subscription_stats group by month,year
union
select null, null ,year,sum(total_payments)
from webassignment.subscription_stats group by year
order by year, month, day
for the sample you provided should be enough
select day, month,year,sum(total_payments)
from webassignment.subscription_stats group by day, month,year
order by day, month,year

How to Extract Months and also show the totals for that month

SR_ AREA INS_PRODUCT DATEADD TOTAL
Clinical Question PS 2016-01-06 280
I'm trying to show the month by name say January and I want all the totals for the month of January not just for one day in the month.
I got it to show just Month and total how do I get it to show all the months this is the code I have so far.
SELECT DATENAME(MM,GETDATE()) AS MONTH, COUNT(*) AS TOTAL
FROM S_SRV_REQ WITH (NOLOCK)
WHERE (dbo.fn_dstoffset(CREATED) >= '11-15-2015')
AND (dbo.fn_dstoffset(CREATED) <= DATEADD(D, 1, '3-31-2016'))
AND (INS_PRODUCT IN ('PS'))
AND [SR_AREA] IS NOT NULL
AND (SR_AREA IN ('Clinical Question'))
select date_format(dateadd, '%M'), sum(total)
from your_table
group by date_format(dateadd, '%M')
You can use MONTH
select month(dateadd), sum(total)
from your_table
group by month(dateadd)

get month wise total, week wise total and day wise total in one mysql query

I want to display month wise total, week wise total and then day wise total with days in one mysql query. I can do it using seperate queries but i want it in single query . Is it possible to display this hierarchy?
by using GROUP BY MONTH we found total by month and GROUP BY WEEK we found total by WEEK
Select sum(column) From table GROUP BY MONTH(column)
union
Select sum(column) From table GROUP BY WEEK(column)
and UNION operator combines the result
This is from link you have provided.
use UNION:
SELECT SUM(cost) AS total, MONTHNAME(date) AS month
FROM daily_expense
GROUP BY month
UNION
SELECT SUM(cost) AS total, CONCAT(date, ' - ', date + INTERVAL 6 DAY) AS week
FROM daily_expense
GROUP BY WEEK(date)

Created date between that particular month mysql

I have a table event, where i have records with a field end_date, so my problem is i want to fetch number of records, grouping month wise, where end_date should with in that month only, so for example:
If a record have end_date as 2013-01-01 00:00:00 then it should be counted in January 2013, and i am not able to do that. I am unable to put that where condition, how to do tell database that end_date should be between the month for which it is currently grouping.
SELECT COUNT(*) AS 'count', MONTH(created) AS 'month', YEAR(created) AS 'year' FROM event WHERE is_approved =1 GROUP BY YEAR(created), MONTH(created)
Please help me out.
EDIT :
Data say i have is like:
Record name end_date
record_1 2013-11-01 00:00:00
record_2 2013-11-30 00:00:00
record_3 2013-12-01 00:00:00
record_4 2013-12-04 00:00:00
record_5 2013-12-06 00:00:00
record_6 2013-12-10 00:00:00
...many more
Result Expected is:
Count month year
2 11 2013
4 12 2013
....so on
Try this:
SELECT COUNT(1) AS 'count', MONTH(end_date) AS 'month', YEAR(end_date) AS 'year'
FROM event
WHERE is_approved = 1
GROUP BY EXTRACT(YEAR_MONTH FROM end_date);
OR
SELECT COUNT(1) AS 'count', MONTH(end_date) AS 'month', YEAR(end_date) AS 'year'
FROM event
WHERE is_approved = 1
GROUP BY YEAR(end_date), MONTH(end_date);
::EDIT::
1. end date is greater than that particular month - Simply add where condition in your query and pass particular month in format of YYYYMM instead of 201411
2. event is started - Add one more where condition to check whether the created date is less then current date
SELECT COUNT(1) AS 'count', MONTH(end_date) AS 'month', YEAR(end_date) AS 'year'
FROM event
WHERE is_approved = 1 AND
EXTRACT(YEAR_MONTH FROM end_date) > 201411 AND
DATE(created) <= CURRENT_DATE()
GROUP BY EXTRACT(YEAR_MONTH FROM end_date);
OR
SELECT COUNT(1) AS 'count', MONTH(end_date) AS 'month', YEAR(end_date) AS 'year'
FROM event
WHERE is_approved = 1 AND
EXTRACT(YEAR_MONTH FROM end_date) > 201411 AND
DATE(created) <= CURRENT_DATE()
GROUP BY YEAR(end_date), MONTH(end_date);
The count is aggregated based on the month and year so if you are spanning years, you wont have Jan 2013 mixed with Jan 2014, hence pulling those values too and that is the same basis of the group by.
As for your criteria, that all goes in the WHERE clause. In this case, I did anything starting with Jan 1, 2013 and ending Dec 31, 2014 via 'yyyy-mm-dd' standard date recognized format. That said, and the structure of the table you provided, I am using the "end_date" column.
SELECT
YEAR(end_date) AS EventYear,
MONTH(end_Date) AS EventMonth,
COUNT(*) AS EventCount
FROM
event
WHERE is_approved = 1
and end_date between '2013-01-01' and '2014-12-31'
GROUP BY
YEAR(end_date),
MONTH(end_Date)
Now, if you want them to have the most recent events on the top, I would put the year and month descending so 2014 is listed first, then 2013, etc and months within them as December (month 12), before the others.
GROUP BY
YEAR(end_date) DESC,
MONTH(end_Date) DESC
Your criteria could be almost anything from as simple as just a date change, approved status, or even get counts per account status is so needed, such as (and these are just EXAMPLES if you had such code status values)
SUM( is_approved = 0 ) as PendingEvent,
SUM( is_approved = 1 ) as ApprovedEvent,
SUM( is_approved = 2 ) as CancelledEvent
Per comment feedback.
For different date ranges, ignore the between clause and change the WHERE to something like
WHERE end_date > '2014-08-01' or all after a date...
where end_date < '2014-01-01' or all before a date...
They will still group by month / year. If you wanted based on a start date of the event, just change that column in instead, or do IN ADDITION to the others.
MySQL has a bunch of date and time functions that can help you with that. For example:
MONTH() Return the month from the date passed
or
YEAR() Return the year
So you can just get the month and year of your dates. And group your results by them.
SELECT
COUNT(*) cnt
,MONTH(end_date) month
,YEAR(end_date) year
FROM events
GROUP BY month, year
Result :
cnt month year
2 11 2013
4 12 2013
Update:
For filtering only the records that have an end_date greater than a particular month AND have already started, you just need to add a WHERE clause. For example, if the particular month were February 2015:
SELECT
COUNT(*) cnt
,MONTH(end_date) month
,YEAR(end_date) year
FROM events
WHERE end_date >= '2015-03-01'
AND created < NOW()
GROUP BY month, year
Alternatively, the first part of the WHERE clause can be rewritten in the following way, which is probably more comfortable to use if you have to pass the year and month as distinct parameters.
...
WHERE (YEAR(end_date) > 2015
OR (YEAR(end_date) = 2015 AND MONTH(end_date) > 02))
AND created...
SELECT COUNT(*) AS 'count', MONTH(created) AS 'month', YEAR(created) AS 'year' FROM event WHERE is_approved =1 and month(created) = "the month u want" and year(created) = "the year you want" group by GROUP BY YEAR(created), MONTH(created)
you will need to pull the month and year... i could help with that but not sure how you are getting it but months would be 01/02/03 ect and year is 2013/2014/2015 ect

mysql if data no exist for in order dates

SELECT
EXTRACT( DAY FROM date) AS day,
EXTRACT( MONTH FROM date) AS month, who, sum ( wsd ) AS total FROM weekly
WHERE season = '08'
AND status = 1
AND who = 'NAME SURNAME'
GROUP BY day, month
day month who total
12 8 NAME SURNAME 18
I am getting totals of "wsd" column for every person in "who" column per day. If one person doesn't have records in table for a day, we can not see that name in the results as expected.
But i want to see that records too, with date and name with "0" in total column.
How can i do it with mysql only?
For this case, you can move the conditional logic from the where to the aggregation -- assuming that you have data for someone on every day:
SELECT EXTRACT( DAY FROM date) AS day, EXTRACT( MONTH FROM date) AS month, who,
sum(case when status = 1 AND who = 'NAME SURNAME' then wsd else 0 end) AS total
FROM weekly
WHERE season = '08'
GROUP BY day, month;
Did you try Coalesce or Isnull for inserting default values(in your case 0) ?