populating a table with dates MYSQL - mysql

I want to populate my table "MyDates" with a range of dates as shown in the code below. When I run the code I get this error "Unknown system variable 'dateStart'"
DECLARE
dateStart DATE DEFAULT '2011-01-01';
DECLARE
dateEnd DATE DEFAULT'2011-12-31';
WHILE dateStart<=dateEnd DO
INSERT
INTO
MyDates
(
mydate
)
VALUES
(
dateStart
) ;
SET dateStart=date_add(dateStart,INTERVAL 1 DAY) ;
END WHILE;
END;

Related

How do I assign DateTime field to a variable

I want to assign value of a query to a datetime variable in MySql Stored Procedure.
I'm trying this -
DECLARE myDate DATETIME;
SET myDate = (SELECT date1 FROM myTable WHERE Id = var_myId);
And this
DECLARE myDate DATETIME;
SELECT date1 into myDate FROM myTable WHERE Id = var_myId;
Both don't seem to work as I am not getting the desired result after running the proc.
EDIT
Problem is in this statement -
initial_Date DATETIME; -- param1
interval INTEGER; -- param2
SET var_date2 = DATE_ADD(initial_Date , INTERVAL interval MINUTE);
When I select var_date2 I get null as result.
I find two issue with your stored procedure.
First, you are naming a variable using an sql key word interval. You should rename with an word which is not an sql key word.
The other is you are not setting an out put variable. You can see the MySQL tutorials on stored procedure.
You can use and try the code below:
delimiter //
create procedure test(in initial_time datetime, in minuteInterval integer(2),
out final_time datetime)
begin
set final_time = date_add(initial_time, interval minuteInterval minute);
end//
delimiter ;
For testing you can try:
call test(now(), 60, #final_time);
select #final_time;
Here is the screenshot of my test with mysql 5.5.21:

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;

insert number of rows based on start and end date

I found a code snippet for sql server and actually have to customize it for mysql while also passing parent table id (event_id).
SQL Server Version
CREATE PROC dbo.t_test
#StartDate DATETIME,
#EndDate DATETIME
AS
WHILE #StartDate <= #EndDate
BEGIN
INSERT INTO YourTable(YourDateField) VALUES (#StartDate)
SET #StartDate = DATEADD(d,1,#StartDate)
END
MySQL Version Attempt
CREATE PROCEDURE `day` (IN start DATE, IN end DATE, IN event_id INT)
BEGIN
WHILE start <= end DO
INSERT INTO day(date, event_id) VALUES(start, event_id);
SET start = start + 1;
END WHILE;
END
My table day structure is
day (id, date, event_id)

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;

MySQL query to show all the hours within the next month

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();