adding date_add but keeping in mide weekends - mysql

i have a mysql query
SELECT CONCAT('document',LEFT(cases.id,26)) AS 'id',
cases.date_modified,
cases.date_modified,
'67421f0a-3f44-1093-1ab6-51750b508349' AS 'assigned_user','1','1','0',
'complete documentation in 4 Days' AS 'name',
'Not Started',
cases.date_modified,
DATE_ADD(cases.date_modified,INTERVAL 4 DAY) AS 'due date','Cases',cases.id,
'P1','Complete Operations Documentation' AS 'description'
FROM cases
INNER JOIN cases_cstm
ON ( cases.id = cases_cstm.id_c)
WHERE cases.`assigned_user_id` = '67421f0a-3f44-1093-1ab6-51750b508349'
AND cases.`status` = 'Start Administration'
AND `cases_cstm`.`file_location` = 'Operations'
ORDER BY `date_modified` DESC
LIMIT 1;
but the problem is on tuesday it will come up for saterday and wednesday it will come up for sunday
and thursday or friday the people will have 2 days les to work?
how can i check that if a weekend fals in the due date to add 2 days?
regards

Try this expression:
(case when weekday(cases.date_modified) = 0
then DATE_ADD(cases.date_modified, INTERVAL 4 DAY)
else DATE_ADD(cases.date_modified, INTERVAL 6 DAY)
end) as 'due date'
It just tests for the day of the week and then adds the appropriate duration to pass the weekend.

The DAYOFWEEK function will return 1 for Sunday, 2 for Monday, 3 for Tuesday, ... through 7 for Saturday. You can use it in a condition like so:
DATE_ADD(cases.date_modified,
CASE DAYOFWEEK(cases.date_modified)
WHEN 3 THEN INTERVAL 6 DAY
WHEN 4 THEN INTERVAL 5 DAY
ELSE INTERVAL 4 DAY
END AS 'due date'
The example above adds 6 days for a Tuesday (going to the next Monday), 5 days for a Wednesday (going to the next Monday), and 4 for all others. This is different than what you asked for (where Wednesday goes to the next Tuesday rather than Monday), but it may be more appropriate. You can tweak as necessary.

Related

How to get the end week of a DATETIME column in mySQL

I am using MySQL and having issues getting the end of the week date from a DATETIME column, where the end of the week is considered Sunday,
My table looks like this:
Unique_ID
Date
123
2020-07-13 17:03:31.035
456
2021-01-01 15:02:19.029
789
2020-08-02 18:07:14.011
I am needing to get the week for each line where the week ends on Sunday. The time isn't needed. So the end result for 2021-01-01 would show 2021-01-03 since that week ends on Sunday. Does anyone know what function to use for this?
Here's an elaboration (I hope) of Akina's suggestion in the comment:
SELECT *,
dt + INTERVAL 6 DAY add6 /*add 6 day ahead*/,
DAYNAME(dt + INTERVAL 6 DAY) dn6 /*6 day ahead dayname*/,
dt + INTERVAL (6 - wkd) DAY nxtsun /*add 6 day ahead then subtract weekday value from date column*/,
DAYNAME(dt + INTERVAL (6 - wkd) DAY) nxtsundn
FROM
(SELECT *,
DATE(date) dt,
DAYNAME(date) dn,
WEEKDAY(date) wkd
FROM mytable) A;
Let's take the second row from your data sample to illustrate what is happening. The base query above:
SELECT *,
DATE(date) dt,
DAYNAME(date) dn,
WEEKDAY(date) wkd
FROM mytable
Will return the following.
Unique_ID
Date
dn
wkd
456
2021-01-01 15:02:19
Friday
4
Note that the WEEKDAY(date) (aliased as wkd in the table) returns 4. Which means it's Friday. According to the docs, WEEKDAY() function returns like the following:
0 = Monday
1 = Tuesday
2 = Wednesday
3 = Thursday
4 = Friday
5 = Saturday
6 = Sunday
Adding 6 day interval to the current WEEKDAY() result goes to the day before next same dayname of the current date value. So WEEKDAY(2021-01-01) which is on Friday, becomes 2021-01-07 which is on Thursday after being added with 6 day ahead. With a subtraction of the pervious obtained WEEKDAY() value, the operation becomes DATE + INTERVAL (6 - 4) DAY, which effectively becomes DATE + INTERVAL 2 DAY.
Here's a fiddle

MySQL date between last monday and the next sunday

i'm looking to find all records that have a booking date between the previous monday and the next sunday in MySQL.
So far I have:
SELECT firstname
, lastname
, sessions
, (SELECT COUNT(memberid)
FROM bookings
WHERE m.memberid = b.memberid
and b.date between lastMonday and nextSunday) as sessionsused
from members
I'm looking what to substitute into the lastmonday and nextsunday
Any help is much appreciated!
MySQL's YEARWEEK() function selects a unique value for each week that you can use for comparison. It takes a second parameter which specifies whether weeks start on Sunday (0) or Monday (1).
SELECT COUNT(memberid)
FROM bookings
WHERE m.memberid = b.memberid
AND YEARWEEK(b.date, 1) = YEARWEEK(NOW(), 1);
This will always select rows where b.date is in the current week. For a specific week in the past, change NOW() for whatever date expression you require.
For the more generic case where your week does not start on a Sunday or a Monday, you will need some slightly more complicated logic. Here you substitute #weekday with the day on which your weeks begin, 2 = Tues, 3 = Wed, 4 = Thu, 5 = Fri, 6 = Sat.
SELECT COUNT(memberid)
FROM bookings
WHERE m.memberid = b.memberid
AND DATE(b.date)
BETWEEN DATE_SUB(DATE(NOW()), INTERVAL (WEEKDAY(NOW()) - #weekday + 7) % 7 DAY)
AND DATE_ADD(DATE(NOW()), INTERVAL 6 - (WEEKDAY(NOW()) - #weekday + 7) % 7 DAY);

how to group by week start from friday

I have table sql like this:
This my query for count tgl:
SELECT count( tgl ) AS total, absen.id
FROM absen
WHERE absen.status = 'm'
GROUP BY absen.id
So I want group by absen.id and absen.tgl
How to group by week from Friday to Thursday?
2016-01-08 is friday and 2016-01-15 is thursday.
Bellow query can bring the result you want, but i think you defined the wrong end date, because in your example from 2015-01-08 up to 2015-01-15 its 8 day and one week has 7 days.
select
count( tgl ) AS total,
absen.id,
CASE WHEN (weekday(tgl)<=3) THEN date(tgl + INTERVAL (3-weekday(tgl)) DAY)
ELSE date(tgl + INTERVAL (3+7-weekday(tgl)) DAY)
END as week_days
FROM absen
WHERE status = 'm'
GROUP BY id,week_days
here is the fiddle fiddle
Query Description:
mysql weekday array numbers:
$weekArr = array(
'Monday' => 0,
'Tuesday' => 1,
'Wednesday' => 2,
'Thursday' => 3,
'Friday' => 4,
'Saturday' => 5,
'Sunday' => 6);
So now suppose today is Tuesday and date is 2016-01-12, now let's count from today towards the start date in our table which is 2016-01-07 and it match with Thursday of past week, so according to the weekday array number its weekday(2016-01-07) == 3 so it goes to the WHEN part of our query, and query will select something like this CASE WHEN (weekday('2016-01-07') <= 3) THEN date('2016-01-07' + INTERVAL(3-3)) that is equal to SELECT '2016-01-07' and so on for others.
I just found how to get this by trouble shooting on excel by using this WEEK('date' + INTERVAL 3 DAY, 3)

Group query results by "today", "in last 7 days", "in last month" and "older"

I have a simple question related to grouping rows by date with some "narrative" periods.
Let's assume that I have very simple table with articles. ID which is PK, title and date. The date column is datetime / timestamp.
I would like to group somehow my results so I can present them in the view like
Written today:
art 944
art 943
Written in last 7 days:
art 823
art 743
Written in last 30 days:
art 520
art 519
art 502
Older:
art 4
art 3
art 1
Can I achieve that in just one single query with some group by statements?
Gordon should have credit for writing this out. But I think you probably just want to append a column with the appropriate descriptor and probably sort them in the order you'd like to see them.
select
title,
case when date = curdate() then 'today'
when date >= curdate() - interval 6 day then 'last 7 days'
when date >= curdate() - interval 29 day then 'last 30 days'
else 'older'
end as bucket,
from ...
order by
case
when date = curdate() then 1
when date >= curdate() - interval 6 day then 2
when date >= curdate() - interval 29 day then 3
else 4
end,
title ...
It looks like you didn't have the titles in alphabetical order. If you want them sorted by age then remove the case expression and just use the date value.
You can use a case statement for the grouping column. Something like this:
select (case when date = curdate() then 'today'
when date >= curdate() - interval 6 day then 'last 7 days'
when date >= curdate() - interval 29 day then 'last 30 days'
else 'older'
end),
count(*),
. . .
from . . .
group by (case when date = curdate() then 'today'
when date >= curdate() - interval 6 day then 'last 7 days'
when date >= curdate() - interval 29 day then 'last 30 days'
else 'older'
end)
Thanks Gordon. It was so simple...
That does what I want.
select
id,
title,
published_at,
(case
when published_at > curdate() then 'future article'
when published_at = curdate() then 'today'
when published_at >= curdate() - interval 6 day then 'last 7 days'
when published_at >= curdate() - interval 29 day then 'last 30 days'
else 'older'
end) as 'when'
from
articles
order by
published_at desc

stuck mysql find last working day in previous month

I would like to ask you that i want to find last working day in previous month in MYSQL.
How to do that ?
this code find last day previous month as the following:
LAST_DAY(Now()- INTERVAL 1 MONTH)
Result that i need as below:
Current Month= 2013-07-01====> Results should be 2013-06-28
Current Month= 2013-06-06====> Results should be 2013-05-31
How to find last working day in previous month ?
Regards
Here’s an example of what I thought of:
LAST_DAY(CURDATE() - INTERVAL 1 MONTH) -
INTERVAL (CASE WEEKDAY(LAST_DAY(CURDATE() - INTERVAL 1 MONTH))
WHEN 5 THEN 1
WHEN 6 THEN 2
ELSE 0 END) DAY
Try something like:
SET #lastworkingday = DATE_SUB(CURDATE(), INTERVAL DAYOFMONTH(CURDATE()) DAY);
// If saturday, take it back one day
IF DAYOFWEEK(#lastworkingday) = 7
THEN #lastworkingday := DATE_SUB(#lastworkingday, INTERVAL 1 DAY);
// If sunday, take it back two days
ELSE IF DAYOFWEEK(#lastworkingday) = 1
THEN #lastworkingday := DATE_SUB(#lastworkingday, INTERVAL 2 DAY);
There may be a more elegant way of writing this (I'd be surprised if there wasn't), but Gumbo's solution might look like this...
Note I've used #dt for testing. You could just substitute CURDATE() in your script.
SET #dt = '2012-07-01'; -- Last day of the previous month (June 2012) was a Saturday
SELECT CASE DAYOFWEEK(LAST_DAY(#dt-INTERVAL 1 MONTH))
WHEN 1 THEN LAST_DAY(#dt-INTERVAL 1 MONTH)-INTERVAL 2 DAY
WHEN 7 THEN LAST_DAY(#dt-INTERVAL 1 MONTH)-INTERVAL 1 DAY
ELSE LAST_DAY(#dt-INTERVAL 1 MONTH)
END x;
+------------+
| x |
+------------+
| 2012-06-29 | -- Friday 29th
+------------+
SET #dt = '2012-08-01'; -- Last day of the previous month (July 2012) was a Tuesday
SELECT CASE DAYOFWEEK(LAST_DAY(#dt-INTERVAL 1 MONTH))
WHEN 1 THEN LAST_DAY(#dt-INTERVAL 1 MONTH)-INTERVAL 2 DAY
WHEN 7 THEN LAST_DAY(#dt-INTERVAL 1 MONTH)-INTERVAL 1 DAY
ELSE LAST_DAY(#dt-INTERVAL 1 MONTH)
END x;
+------------+
| x |
+------------+
| 2012-07-31 | -- Tuesday 31st
+------------+
SET #dt = '2012-10-01'; -- Last day of the previous month (September 2012) was a Sunday
SELECT CASE DAYOFWEEK(LAST_DAY(#dt-INTERVAL 1 MONTH))
WHEN 1 THEN LAST_DAY(#dt-INTERVAL 1 MONTH)-INTERVAL 2 DAY
WHEN 7 THEN LAST_DAY(#dt-INTERVAL 1 MONTH)-INTERVAL 1 DAY
ELSE LAST_DAY(#dt-INTERVAL 1 MONTH)
END x;
+------------+
| x |
+------------+
| 2012-09-28 | -- Friday 28th
+------------+
Another way is to build a calendar table of all dates. Ignoring public holidays, the first and last working days of the month then are simply the min and max weekdays of the month.
Although, there is an argument that goes 'so why not just figure this bit out in your application code'!
To get last working date you have to follow following steps :
1. first of all get last date of last month .
2.check whether it is working day or not by weekday function . if it is sunday then subtract 2 from lastdate , if it is saturday then subtract 1 from lastdate otherwise do not change anything .
we can do this thing by case statement . check following query . it will really works :
SELECT
CASE WEEKDAY(LAST_DAY(CONCAT(YEAR(CURDATE()),'-' , MONTH(CURDATE())-1 ,'-' , 1)))
WHEN 6
THEN DATE_ADD(LAST_DAY(CONCAT(YEAR(CURDATE()),'-' , MONTH(CURDATE())-1 ,'-' , 1)),INTERVAL -2 DAY)
WHEN 5
THEN DATE_ADD(LAST_DAY(CONCAT(YEAR(CURDATE()),'-' , MONTH(CURDATE())-1 ,'-' , 1)),INTERVAL - 1 DAY)
ELSE
LAST_DAY(CONCAT(YEAR(CURDATE()),'-' , MONTH(CURDATE())-1 ,'-' , 1)) END;
http://sqlfiddle.com/#!2/d41d8/15940
if you subtract the day of current month then you will get the last day of previous month
(DATE_SUB(CURDATE(),INTERVAL DAYOFMONTH(CURDATE()) DAY))
For example, on the 12th of the month if we subtract 12 days,then well get the the last day of the previous month: