MySQL query to show all the hours within the next month - mysql

How would I put together a query to display all of the hours in the next week as I want to compare a timetable against this for appointment purposes.
Thanks for any help!
edit--
the expected result would be great as between 9 to 5
| client_date | client_time |
10/01/2010 09:00:00
10/01/2010 10:00:00
10/01/2010 11:00:00
10/01/2010 12:00:00
10/01/2010 13:00:00
10/01/2010 14:00:00
10/01/2010 15:00:00
10/01/2010 16:00:00
10/01/2010 17:00:00

You will need to create a table to store the date and time values.
CREATE TABLE calendarhours (caldaytime DATETIME);
You will then need to create a stored procedure to loop through the two dates and insert the date time values for the time sheet times into the table.
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `timesheetdays`(startdate DATETIME, enddate DATETIME)
BEGIN
DECLARE tempdate DATETIME;
DELETE FROM `calendarhours`;
-- set the temp date to 9am of the start date
SET tempdate = DATE_ADD(DATE(startdate), INTERVAL '0 9' DAY_HOUR);
-- while the temp date is less than or equal to the end date, insert the date
-- into the temp table
WHILE ( tempdate <= enddate ) DO
BEGIN
-- insert temp date into temp table
INSERT INTO `calendarhours` (caldaytime) VALUES (tempdate);
-- increment temp date by an hour
SET tempdate = DATE_ADD(tempdate, INTERVAL '0 1' DAY_HOUR);
-- if the temp date is greater than 5 PM (17:00) then increment to the next day
IF TIMEDIFF(tempdate, DATE_ADD(DATE(tempdate), INTERVAL '0 17' DAY_HOUR)) > 0 THEN
BEGIN
-- increment to the next day
SET tempdate = DATE_ADD(DATE(tempdate), INTERVAL '1 9' DAY_HOUR);
-- for business purposes, if the day is a Saturday or a Sunday increment
-- until we reach Monday
WHILE ( DAYNAME(tempdate) = 'Saturday' OR DAYNAME(tempdate) = 'Sunday' ) DO
BEGIN
SET tempdate = DATE_ADD(DATE(tempdate), INTERVAL '1 9' DAY_HOUR);
END;
END WHILE;
END;
END IF;
END;
END WHILE;
-- return all the inserted date and times
SELECT * FROM calendarhours ORDER BY caldaytime;
END
This procedure will then loop through the two dates, starting from 9 am each day and finishing at 5pm each day (17:00). When the time reaches 18:00, the procedure increments to the next day and starts again at 9 am.
If you are doing a standard business week timesheet, then if the day is equal to Saturday or Sunday, it will increment until it reaches Monday.
To test this I used the following statements:
CALL `timesheetdays`(NOW(), DATE_ADD(DATE(NOW()), INTERVAL '5 0' DAY_HOUR));
SELECT * FROM `calendarhours`;
This tests the procedure from today to 5 days from today and shows the hours as required. The first statement adds the records to the table and then returns the records, the second statement returns the records from the table.

you can use a temporary table in a stored procedure.
DELIMITER ;;
DROP PROCEDURE IF EXISTS ListHours ;;
CREATE PROCEDURE ListHours()
BEGIN
DECLARE curDT DATETIME;
DECLARE today DATETIME ;
DECLARE nextSaturday DATETIME;
DECLARE nextSunday DATETIME;
DECLARE iterDate DATETIME;
DECLARE iterDateTime DATETIME;
DECLARE iterBound DATETIME;
DECLARE resDate DATETIME;
DECLARE resTime DATETIME;
DECLARE delta INT;
DROP TABLE IF EXISTS tempNextWeek;
CREATE TEMPORARY TABLE IF NOT EXISTS tempNextWeek
(
client_date VARCHAR(20),
client_time VARCHAR(20)
);
DELETE FROM tempNextWeek;
SET curDT = NOW();
SET today = ADDTIME(SUBTIME(curDT , TIME(curDT)) , '9:0:0');
SET delta = 8 - DAYOFWEEK(today);
SET nextSunday = ADDDATE(today , INTERVAL delta DAY);
SET nextSaturday = ADDTIME(nextSunday , '6 0:0:0');
-- select today , delta , nextSaturday , nextSunday ;
SET iterDate = nextSunday;
WHILE iterDate <= nextSaturday DO
SET iterDateTime = iterDate;
SET iterBound = ADDTIME(iterDateTime, '8:0:0');
WHILE iterDateTIme <= iterBound DO
INSERT tempNextWeek (client_date, client_time) VALUE ( DATE_FORMAT(iterDateTime, '%Y-%m-%d'), DATE_FORMAT(iterDateTime, '%H:%i:%s') );
SET iterDateTime = ADDTIME(iterDateTime , '1:0:0');
END WHILE;
SET iterDate = ADDTIME(iterDate , '1 0:0:0');
END WHILE ;
SELECT * FROM tempNextWeek;
-- drop table if exists tempNextWeek;
END;;
DELIMITER ;
CALL ListHours();

Related

Create a loop based on date Mysql

I have a query :
insert into fookoo_business
select stat_date, sum(spend), sum(revenue)
from hooloo_business;
that i want to run for each date from '2017-01-20' until yesterday (it means the query will run 434 times if we're at 01/04/2018), for each date separately
(in a loop).
how can i create a loop in Mysql to do it for me?
I have tried:
creating procedure for the query select #stat_date, sum(spend), sum(revenue)
I called 'query'
then :
CREATE PROCEDURE loop_procedure()
BEGIN
SET #stat_date='2018-03-20';
CALL 'query';
REPEAT
SET #stat_date = #stat_date + INTERVAL 1 DAY;
UNTIL #stat_date = CURDATE() END REPEAT;
END
eventually i've used the following logic within a stored procedure to fetch the data:
PROCEDURE `x_monitoring_loop`()
BEGIN
DECLARE i INT;
DECLARE len INT;
SET len = 434;
SET i = 0;
WHILE (i < len) DO
SET #stat_date= CURDATE()-INTERVAL 1 DAY;
SET #stat_date= #stat_date- INTERVAL i DAY;
Insert query;
SET i = i +1;
END WHILE;
This way the query ran 434 times for each day, beginning at current date - 1 day.
I do not know why you want to use a procedure,I think we can just use a query sql to do it:
INSERT INTO fookoo_business
SELECT stat_date, SUM(spend), SUM(revenue)
FROM hooloo_business
WHERE stat_date BETWEEN STR_TO_DATE('2017-01-02', '%Y-%m-%d') -- start date
AND DATE_SUB(NOW(), INTERVAL 1 DAY) -- end date
GROUP BY stat_date;

Update and Insert table rows using a Mysql stored procedure

I have a table book_meetings which have 70000 record and I want to migrate this data into another table with little modification for this I have created a Mysql stored procedure. Records are inserted in new table but values are set as null.
I am selecting only four columns from book_meetings table and wants to insert them in table.
id int
date date
meet_at time
duration_in_hours decimal
What I want is calculate the start_date and end_date based on above values.
For example:
if date ="2017-09-08" , meet_at is "09:00:00" and duration_in_hours is 1.5
then start_date will be "2017-09-08 09:10:00"
end_date= start_date_duration_in_hour
end_date will be "2017-09-08 09:10:00"
start_date = concat date and meet_at
end_date = start_date + duration_in_hours
and insert this values in new table
if there is another better idea then please suggest
CREATE PROCEDURE book_meetings8()
BEGIN
-- Declare local variables
DECLARE done BOOLEAN DEFAULT 0;
DECLARE meet_at TIME;
DECLARE start_date DATETIME;
DECLARE tmp_date VARCHAR(255);
DECLARE end_date DATETIME;
DECLARE end_recurring_date DATE;
DECLARE date1 DATE ;
DECLARE id INTEGER(11);
DECLARE duration DECIMAL(8,2);
DECLARE minutes INTEGER(11);
-- Declare the cursor
DECLARE iter CURSOR
FOR
SELECT id,date, meet_at,duration_in_hours FROM
book_meetings LIMIT 100;
-- Declare continue handler
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
-- Open the cursor
OPEN iter;
-- Loop through all rows
REPEAT
-- Get order number
FETCH iter INTO id,date1,meet_at,duration;
SET minutes = duration * 60;
SET start_date = CAST(date1 as char) + " "+CAST(meet_at as
char);
SET end_date = CAST(start_date as datetime) + INTERVAL
minutes MINUTE;
INSERT INTO
book_meetings_1(start_date,end_date)
VALUES(start_date,end_date);
-- End of loop
UNTIL done END REPEAT;
-- Close the cursor
CLOSE iter;
END;
Well I have solved above problem with single SQL statement (Insertion and updation all record at once without store procedure)
INSERT INTO temp_diary.book_meetings ( id,start_date,end_date) SELECT id,CONCAT(`date`, ' ', `meet_at`) as start_date,DATE_ADD(concat(date,' ',meet_at), INTERVAL `duration_in_hours` HOUR) as end_date FROM estate.book_meetings;

Stored procedure MySQL 5.5.16

So I have in my database a table called "weeks" where I store every weeks of the years like so:
table weeks(id, year, num_week, date_min, date_max)
So for this week, the line look like this :
Note : My weeks starts on thursday and ends on Wenesday.
Since it is a pain inserting each weeks line by line, I want to create a stored procedure for this, here's what I came up with :
DELIMITER |
CREATE PROCEDURE proc_insert_weeks()
BEGIN
SELECT year, num_week, date_min, date_max INTO #year, #num_week, #date_min, #date_max
FROM weeks
ORDER BY date_min DESC LIMIT 1;
SET #date_min = DATE_ADD(#date_max INTERVAL 1 DAY);
SET #date_max = DATE_ADD(#date_min INTERVAL 6 DAY);
SET #year= YEAR(#date_min);
IF #num_week < 52 THEN SET #num_week = #num_week + 1;
ELSE SET #num_week = 1;
END IF;
INSERT INTO weeks (year, num_week, date_min, date_max)
VALUES (#year, #num_week, #date_min, #date_max);
END |
DELIMITER ;
So the idea was to take the last record of the table and add 1 week to the dates, but I can't even make it paste the creation of the procedure.
I get an error right after the SELECT query, can someone help me figure out what I am doing wrong ?
drop PROCEDURE proc_insert_weeks;
DELIMITER |
CREATE PROCEDURE proc_insert_weeks()
BEGIN
SELECT year, num_week, date_min, date_max INTO #year, #num_week, #date_min, #date_max
FROM weeks
ORDER BY date_min DESC LIMIT 1;
SET #date_min = DATE_ADD(#date_max, INTERVAL 1 DAY);
SET #date_max = DATE_ADD(#date_min, INTERVAL 6 DAY);
SET #year= YEAR(#date_min);
IF #num_week < 52 THEN SET #num_week = #num_week + 1;
ELSE SET #num_week = 1;
END IF;
INSERT INTO weeks (year, num_week, date_min, date_max)
VALUES (#year, #num_week, #date_min, #date_max);
END |
DELIMITER ;
You can try above code.
You made mistake in DATE_ADD function. You missed , in it.

Date of the week in MySQL

I have table in MySQL which contain data like,
Week No. Month Year
1 April 2016
4 April 2016
I need to find date of Monday for the particular week.
I think this should do the trick, maybe you should have to adjust type of y parameter.
DELIMITER $$
CREATE FUNCTION `calc_date`(y TEXT, m TEXT, w INT)
RETURNS date
BEGIN
DECLARE d DATE;
SET d = DATE_ADD(STR_TO_DATE(CONCAT(CONCAT(CONCAT(y,'-'),m),'-01'), '%Y-%M-%d'), INTERVAL w week);
RETURN DATE_SUB(d, INTERVAL (DAYOFWEEK(d) + 5)%7 DAY);
end;
$$
DELIMITER ;
then you just have to call
select calc_date(`Year`,`Month`,`Week No.`) from yourtable;

Un-group a row into many rows based on date parts

I'm using MySql and I have a Policy table with StartDate and EndDate columns.
How can I write a SELECT query to give me a new row for each month in the date range between these 2 columns.
For example if I have a policy with:
Id StartDate EndDate
123456 2011-05-25 2011-07-26
I would want to see:
Id PolicyId StartDate EndDate
1 123456 2011-05-25 2011-06-24
2 123456 2011-06-25 2011-07-24
3 123456 2011-07-25 2011-07-26
I'm not sure about performance because I'm not much experienced with stored procedures so there might be a better approach. Also, you might want to change the structure of the temporary table (aka. PolicyList). Anyway…
This can also be converted into before/after triggers instead of executing it each time.
DROP PROCEDURE IF EXISTS CreatePolicyList;
DELIMITER //
CREATE PROCEDURE CreatePolicyList()
BEGIN
DECLARE origId, done INT DEFAULT 0;
DECLARE startD, endD DATE;
DECLARE cur CURSOR FOR
SELECT id, StartDate, EndDate FROM Policy;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DROP TEMPORARY TABLE IF EXISTS PolicyList;
CREATE TEMPORARY TABLE PolicyList (
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
PolicyId INT(11) NOT NULL,
StartDate DATE NOT NULL,
EndDate DATE NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
OPEN cur;
recLoop: LOOP
FETCH cur INTO origId, startD, endD;
IF (done)
THEN LEAVE recLoop;
END IF;
-- following is an alternative to keep records like
-- "2011-05-25, 2011-06-25" in a single record
-- WHILE startD < DATE_SUB(endD, INTERVAL 1 MONTH) DO
WHILE startD < DATE_ADD(DATE_SUB(endD, INTERVAL 1 MONTH), INTERVAL 1 DAY) DO
INSERT INTO PolicyList (PolicyId, StartDate, EndDate)
VALUES (origId, startD,DATE_SUB(
DATE_ADD(startD, INTERVAL 1 MONTH),
INTERVAL 1 DAY
));
SET startD = DATE_ADD(startD, INTERVAL 1 MONTH);
END WHILE;
IF startD >= DATE_SUB(endD, INTERVAL 1 MONTH) THEN
INSERT INTO PolicyList (PolicyId, StartDate, EndDate)
VALUES (origId, startD, endD);
END IF;
END LOOP;
CLOSE cur;
END //
CALL CreatePolicyList;
and then query:
SELECT * FROM PolicyList
ORDER BY PolicyId, StartDate;