Selecting values using day as a variable - mysql

In my project one of the tasks is to run a daily report of all new reports and jobs that have been conducted in the preceding 24 hours easy..
However they throw in a funny in terms of the repair crews do not work over the weekend however reports could naturally still come in. So Monday morning a report will be produced show all reports from the past 3 days eg fri - mon and any repairs conducted on the fri similar to the code below.
One solution which I find unpracticle is to show two date fieds and the user selects fri & mon date like code I produced below for another function.
SELECT `defect_Id`, `job_Id`, `date_On_Task`, `description`, `resolved`
FROM `job`
WHERE `date_On_Task` >= '$date1'
AND `date_On_Task` <= '$date2'
AND `repair_Team` = '$repair_Team'
AND `resolved` = 3"
I would like to be able to use if statement with nested sql statements if day = Monday show * <3days if not show * <1 day.
The select statement is an issue I'm struggling to find any information on a variable of a day for example on click CURDATE() would select current date but can SQL convert a date to a day?

You could get rid of both date pickers from your application.
For that you could apply your logic in WHERE clause using CASE statement:
WHERE
CASE WHEN WEEKDAY(CURRENT_DATE) = 0
THEN `date_On_Task` = CURRENT_DATE - INTERVAL 3 DAY
ELSE `date_On_Task` = CURRENT_DATE - INTERVAL 1 DAY
END
WEEKDAY() function returns 0 for Monday and will cause the following where clause to apply on Mondays:
WHERE `date_On_Task` = CURRENT_DATE - INTERVAL 3 DAY
If the function returns anything else (from 1 to 6 meaning Tuesday to Sunday) get jobs that have been performed yesterday.
Substracting days from a particular date is straightforward. You could use DATE_SUB() or substract INTERVAL like that:
<DATE HERE> - INTERVAL <NUMBER HERE> DAY
Your full query would look:
SELECT `defect_Id`, `job_Id`, `date_On_Task`, `description`, `resolved`
FROM `job`
WHERE
CASE WHEN WEEKDAY(CURRENT_DATE) = 0
THEN `date_On_Task` = CURRENT_DATE - INTERVAL 3 DAY
ELSE `date_On_Task` = CURRENT_DATE - INTERVAL 1 DAY
END
AND `repair_Team` = '$repair_Team'
AND `resolved` = 3

Kind of like this(?):
WHERE
[date_On_Task] BETWEEN
CASE
WHEN DATENAME(DW, GETDATE()) = 'Monday' THEN CAST(GETDATE() - 3 AS date)
WHEN DATENAME(DW, GETDATE()) = 'Sunday' THEN CAST(GETDATE() - 2 AS date)
ELSE CAST(GETDATE() - 1 AS date)
END
AND
CAST(GETDATE() AS date)

Related

How can i adapt by query to get the last BUSINESS/WORKING day of each month in MYSQL?

all,
trying to adapt the below query to get this for the last business day of say month may, june or whatever?
select distinct
month(createddate),
year(CreatedDate),
id,
value1,
vaue2,
createddate,
count( distinct id)
from
table
and value2 IN ('harry','sally')
AND createddate > LAST_DAY( '2020-05-21') ## i need last business day here for may.
AND createddate < '2020-06-01' ## i need first day of next month here
group by month(createddate),
year(CreatedDate), id,value1, value2,createddate
ive not used mysql in a while, is there a way i can use a function or stored procedures to find this out? if so how
*** by business day i mean working day, not a weekend***
Presumably, you want to avoid weekend days. So:
(createddate > last_day('2020-05-21') and dayofweek(last_day('2020-05-21') between 2 and 6 or
createddate > last_day('2020-05-21') - interval 1 day and dayofweek(last_day('2020-05-21') = 7 or
createddate > last_day('2020-05-21') - interval 2 day and dayofweek(last_day('2020-05-21') = 1
)

How can I make my select always use the current week?

Good day dear developers, I have a task to make my SELECT " always contain current weekly payment records", how can I do this, what I need to do with my duedate?
Thanks for your attention.
My select :
SELECT duedate, interest_amount , completed_derived,
(principal_amount + interest_amount) AS weekly_payment_amount
FROM `loan-schema`.m_loan_repayment_schedule
WHERE completed_derived = 0;
Output :
It looks like you want records that belong to the current week only. For this, you need some kind of date arithmetics, whose actual implementatation depends on your database.
In MySQL:
select ...
from ...
where
completed_derived = 0
and duedate >= current_date - interval weekday(current_date) day
and duedtae < current_date + interval (7 - weekday(current_date)) day
In Oracle:
and duedate >= trunc(sysdate, 'iw')
and duedtae < trunc(sysdate, 'iw') + interval '7' day

Dynamic due date finder in a single query

id start_date interval period
1 2018-01-22 2 month
2 2018-02-25 3 week
3 2017-11-24 3 day
4 2017-07-22 1 year
5 2018-02-25 2 week
the above is my table data sample. start_dates will be expired based on interval and period(i.e id-1 will have due date after 2 months from the start_date, id-2 will have due after 3 weeks vice versa). period is enum of (day,week,month,year). requirement is, Client can give any period of dates. let's say 25-06-2026 to 13-07-2026 like that.. I have to return the ids whose due dates falls under that period.I hope i made my question clear.
I am using mysql 5.7. I found a way to achieve this with recursive CTE's.(not available in mysql 5.7). and there is a way to achieve this by populating virtual records by using inline sub queries along with unions but its a performance killer and we can't do populate virtual records every time a client request comes.(like given in the link Generating a series of dates) I have reached a point to get results for a single date which is very easy. Below is my query.
SELECT b.*
FROM (SELECT a.*,
CASE
WHEN period = 'week' THEN MOD(Datediff('2018-07-22', start_date), 7 * intervals)
WHEN period = 'month'
AND Day('2018-07-22') = Day(start_date)
AND MOD(Period_diff(201807, Extract(YEAR_MONTH FROM start_date)), intervals) = 0 THEN 0
WHEN period = 'year'
AND Day('2018-07-22') = Day(start_date)
AND MOD(Period_diff(201807, Extract(
YEAR_MONTH FROM start_date)) / 12,
intervals) = 0 THEN 0
WHEN period = 'day' THEN MOD(Datediff('2018-07-22', start_date) , intervals)
end filters
FROM kml_subs a)b
WHERE b.filters = 0;
But I need to do this for a period of dates not a single date. Any suggestions or solutions will be much appreciated.
My desired result shoud be like..
if i give two dates.say 2030-05-21 & 2030-05-27. due dates falls under those 6 dates between(2030-05-21 & 2030-05-27) will be shown in the result.
id
1
4
My question is different from Using DATE_ADD with a Column Name as the Interval Value . I am expecting a dynamic way to check due dates based on start_date
Thanks, Kannan
In MySQL, it would seem that a query along these lines would suffice. (Almost) everything else could and should be handled in application level code...
SELECT *
, CASE my_period WHEN 'day' THEN start_date + INTERVAL my_interval DAY
WHEN 'week' THEN start_date + INTERVAL my_interval WEEK
WHEN 'month' THEN start_date + INTERVAL my_interval MONTH
WHEN 'year' THEN start_date + INTERVAL my_interval YEAR
END due_date
FROM my_table;

SQL Query for reservation dates that break a month end?

I'm using a custom PHP function to produce a visual calendar for a single month that blocks out dates based on a table that contains an start date, and an duration - For example:
...This is produced by data saying that the table should be blocked out for 4 days from the 14th, and 7 days from the 27th.
The query looks something like this:
SELECT GROUP_CONCAT(DATE_FORMAT(start_date,'%d'),':', event_duration) AS info
FROM events
WHERE YEAR(start_date = '2012'
AND MONTH(start_date) = '07'
ORDER BY start_date
(You could safely ignore the group concat and return the data as individual rows, that doesn't really matter).
I'm looking for a modification to the query that would block out dates at the start of the month IF an event starts in the previous month, but its length takes it into the following.
For instance - in the above example, the event on the 27th is actually scheduled to last 7 days in the database, so if I ran the query for MONTH(start_date) = '08' I'd like to say the first two dates blocked out, which they wouldn't currently be, because the start date that would block it out is not in the month being selected.
I'm fairly sure there's a subquery or something in there to grab the rows, but I just can't think of it. Any takers?
EDIT
The answer from Salman below pointed me in the directon I wanted to go, and I came up with this as a way of getting carryovers from the previous month to show as '1st' of the month with the number of remaining days:
SELECT IF(MONTH(start_date) < '08', '2012-08-01', start_date) AS starter,
IF(MONTH(start_date) < '08', duration - DATEDIFF('2012-08-01',start_date), duration) AS duration
FROM EVENTS
WHERE YEAR(start_date) = '2012'
AND (MONTH(start_date) = '08' OR MONTH(start_date + INTERVAL duration DAY) = '08')
Obviously a lot of variables there to replace in PHP, so maybe there's an even better way?
Original Answer:
Assuming that the month in question is 2012-07, you need this query:
SELECT column1, column2, columnN
FROM `events`
WHERE `start_date` <= '2012-07-01'
AND `start_date` + INTERVAL `duration` DAY > '2012-07-01'
ORDER BY start_date
Revised Answer:
Apparently you need a query that checks for overlapping (or conflicting) dates. The example dates are 2012-07-01 through 2012-08-01 and the query is:
SELECT *
FROM events
WHERE '2012-08-01' > start_date
AND start_date + INTERVAL duration DAY > '2012-07-01'
ORDER BY start_date
To constrain the start date and interval, you can use SELECT ... CASE statement:
SELECT
CASE
WHEN start_date < '2012-07-01' THEN '2012-07-01'
ELSE start_date
END AS start_date_copy,
CASE
WHEN start_date < '2012-07-01' THEN duration - DATEDIFF('2012-07-01', start_date)
ELSE duration
END AS duration_copy,
FROM ...
The answer I was looking for, thanks to the other contributor for pointing me in the right direction and enabling me to solve it!
This is based on $yyyy and $mm coming from PHP (in my case, into a function call), and selecting individual rows rather than grouping:
SELECT start_date, duration
FROM reservations
WHERE YEAR(start_date) = '".$yyyy."'
AND MONTH(start_date) = '".$mm."'
UNION
SELECT '".$yyyy."-".$mm."-01',
duration - DATEDIFF('".$yyyy."-".$mm."-01',start_date)
FROM reservations
WHERE YEAR(start_date) = '".$yyyy."'
AND MONTH(start_date) < '".$mm."'
AND MONTH(start_date + INTERVAL duration DAY) = '".$mm."'
ORDER BY start_date

How do I get the first day of the week of a date in mysql?

Suppose I have 2011-01-03 and I want to get the first of the week, which is sunday, which is 2011-01-02, how do I go about doing that?
The reason is I have this query:
select
YEAR(date_entered) as year,
date(date_entered) as week, <-------This is what I want to change to select the first day of the week.
SUM(1) as total_ncrs,
SUM(case when orgin = picked_up_at then 1 else 0 end) as ncrs_caught_at_station
from sugarcrm2.ncr_ncr
where
sugarcrm2.ncr_ncr.date_entered > date('2011-01-01')
and orgin in(
'Silkscreen',
'Brake',
'Assembly',
'Welding',
'Machining',
'2000W Laser',
'Paint Booth 1',
'Paint Prep',
'Packaging',
'PEM',
'Deburr',
'Laser ',
'Paint Booth 2',
'Toolpath'
)
and date_entered is not null
and orgin is not null
AND(grading = 'Minor' or grading = 'Major')
and week(date_entered) > week(current_timestamp) -20
group by year, week(date_entered)
order by year asc, week asc
And yes, I realize that origin is spelled wrong but it was here before I was so I can't correct it as too many internal apps reference it.
So, I am grouping by weeks but I want this to populate my chart, so I can't have all the beginning of weeks looking like different dates. How do I fix this?
If the week starts on Sunday do this:
DATE_ADD(mydate, INTERVAL(1-DAYOFWEEK(mydate)) DAY)
If the week starts on Monday do this:
DATE_ADD(mydate, INTERVAL(-WEEKDAY(mydate)) DAY);
more info
If you need to handle weeks which start on Mondays, you could also do it that way. First define a custom FIRST_DAY_OF_WEEK function:
DELIMITER ;;
CREATE FUNCTION FIRST_DAY_OF_WEEK(day DATE)
RETURNS DATE DETERMINISTIC
BEGIN
RETURN SUBDATE(day, WEEKDAY(day));
END;;
DELIMITER ;
And then you could do:
SELECT FIRST_DAY_OF_WEEK('2011-01-03');
For your information, MySQL provides two different functions to retrieve the first day of a week. There is DAYOFWEEK:
Returns the weekday index for date (1 = Sunday, 2 = Monday, …, 7 = Saturday). These index values correspond to the ODBC standard.
And WEEKDAY:
Returns the weekday index for date (0 = Monday, 1 = Tuesday, … 6 = Sunday).
If week starts on Monday
SELECT SUBDATE(mydate, weekday(mydate));
If week starts on Sunday
SELECT SUBDATE(mydate, dayofweek(mydate) - 1);
Example:
SELECT SUBDATE('2018-04-11', weekday('2018-04-11'));
2018-04-09
SELECT SUBDATE('2018-04-11', dayofweek('2018-04-11') - 1);
2018-04-08
Week starts day from sunday then get First date of the Week and Last date of week
SELECT
DATE("2019-03-31" + INTERVAL (1 - DAYOFWEEK("2019-03-31")) DAY) as start_date,
DATE("2019-03-31" + INTERVAL (7 - DAYOFWEEK("2019-03-31")) DAY) as end_date
Week starts day from Monday then get First date of the Week and Last date of week
SELECT
DATE("2019-03-31" + INTERVAL ( - WEEKDAY("2019-03-31")) DAY) as start_date,
DATE("2019-03-31" + INTERVAL (6 - WEEKDAY("2019-03-31")) DAY) as end_date
select '2011-01-03' - INTERVAL (WEEKDAY('2011-01-03')+1) DAY;
returns the date of the first day of week. You may look into it.
This is a much simpler approach than writing a function to determine the first day of a week.
Some variants would be such as
SELECT DATE_ADD((SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE())+1)DAY),INTERVAL 7 DAY) (for the ending date of a query, such as between "beginning date" and "ending date").
SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE())+1) DAY (for the beginning date of a query).
This will return all values for the current week. An example query would be as follows:
SELECT b.foo FROM bar b
WHERE b.datefield BETWEEN
(SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE())+1) DAY)
AND (SELECT DATE_ADD((SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE())+1)DAY),INTERVAL 7 DAY))
This works form me
Just make sure both dates in the below query are the same...
SELECT ('2017-10-07' - INTERVAL WEEKDAY('2017-10-07') Day) As `mondaythisweek`
This query returns: 2017-10-02 which is a monday,
But if your first day is sunday, then just subtract a day from the result of this and wallah!
If the week starts on Monday do this:
DATE_SUB(mydate, INTERVAL WEEKDAY(mydate) DAY)
SELECT MIN(DATE*given_date*) FROM *table_name*
This will return when the week started at for any given date.
Keep the good work going!