Updating a column based on another column + interval - mysql

Our database currently has a course_start_date, but not a course_end_date. My goal is to set each course _end_date based on course_start_date + 3 days based on course_type_id. course_start_date is currently stored as a unix_timestamp. Here is my code.
UPDATE system_course
SET course_end_date = 'UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(course_start_date), INTERVAL 3 DAY))'
WHERE course_type_id = '1'
This code is placing 0 in everything.
Both course_start_date and course_end_date are structured:
INT(11) unassigned
Running the following code shows me good results (obviously End Date is not stored in the db)
SELECT FROM_UNIXTIME(course_start_date) as "Start Date", DATE_ADD(FROM_UNIXTIME(course_start_date), INTERVAL 4 DAY) as "End Date"
FROM system_course
WHERE course_type_id = '1'
Select Results:
Start Date End Date
2011-10-31 07:30:00 2011-11-03 07:30:00
Can I not use row parameters in the set column? How do I get around this?

Your UNIX_TIMESTAMP is in single quotes, this will treat it as a string and cast to zero as demonstrated. What you want is this;
SET course_end_date = UNIX_TIMESTAMP(DATE_ADD(FROM_UN...

Related

how to shift back the date by a certain number of days v2

I have the following problem: I have a table in which in the first column there are dates, in the second information whether a day is a working day or not (1 or 0) and in the third, the number of working days by which the value from the first column should be shift back. Anyone have maybe think how to get this fourth column?
The table looks something like this:
date
workday
days back
10.01.2021
1
1
10.01.2021
1
2
10.01.2021
1
3
10.01.2021
1
4
11.01.2021
0
1
11.01.2021
0
2
11.01.2021
0
3
11.01.2021
0
4
12.01.2021
1
1
12.01.2021
1
2
12.01.2021
1
3
12.01.2021
1
4
or otherwise .... the third column is the number of working days needed to make a given product. The first column is the date when the product have to be ready.
I need in column nr 4 the date (the working day) in which to start production. For example for line 9 it will be 10.012021 This view is supposed to be a combination of product realization dates and production start dates for different production lifecycle values.
You either need every working day in your table or you need a separate table with a every day and whether it is a working day or not.
I'm not familiar with mysql, the below is my attempt to translate something that works in MS SQL Server, I'm hoping it will work in mysql.
Below I've assumed your only table is called Table1 and it has every working day in and is the table from your question.
First you need to create a function
CREATE FUNCTION [OffsetDate]
(
#StartDate DATE NULL,
#OffsetDays INT = 0
)
RETURNS DATE
AS
BEGIN
DECLARE #Result DATE
SET #Result = #StartDate
BEGIN
SELECT #Result = distinctDates.Date
FROM (SELECT DISTINCT Table1.Date
FROM Table1
WHERE Table1.Date <= #StartDate
AND Table1.WorkDay = 1) AS distinctDates
ORDER BY distinctDates.Date DESC
LIMIT 1 OFFSET #OffsetDays
END
RETURN #Result
END
Then use this in a query to get your 4th column:
SELECT Table1.Date, Table1.WorkDay, Table1.[Days Back], OffsetDate(Table1.Date, Table1.[Days Back]) AS StartDate
FROM Table1

Check if date range is in month (calendar)

I'm trying to check with sql if a date range (with start and end date) is in a month (regarding year). Month and year are given variables (GET-variables).
This is my table:
+----+------+-------+-----+
| id | name | start | end |
+----+------+-------+-----+
Because an appointment could be just one date (start and end would be the same date), I have to consider this.
My query
SELECT
id,
name,
start,
end
FROM appointments
WHERE (MONTH(start) = ? AND YEAR(end) = ?) OR (MONTH(start) = ? AND YEAR(end) = ?)
ORDER BY start
The problem with this query is that it just checks the start-month and the end-month not the months between. For example if an appointment is over 5 months, this query fails.
If you want to know if a particular month is in the range, then I would suggest turning the dates into a YYYYMM format. This makes the logic relatively easy to express:
where ?*100 + ? between year(start)*100 + month(start) and
year(end)*100 + month(end)

How to set flag variable if year is changed in comparing two dates

Suppose for example i have start date 31-12-2013 & end date 6-01-2014. i want to set a flag =1 in sql server database table if start date is in previous year & end date is in the next year. how to do this?
You can do this by using computed column.
For example, I have created a table with the following script:
create table tblcomputedsample
(start_date datetime,
end_date datetime,
Flag As (case when year(end_date) - year(start_date) = 1 then 1 else 0 end)
)
Note the column Flag, which will automatically get the value based on the values in start_date and end_date fields.
Insert some values and check the data.
I inserted some sample data:
insert into tblcomputedsample
values('1-Mar-2014','10-Nov-2014'),('1-Mar-2013','10-Nov-2014'),
('1-Mar-2014','10-Nov-2015'),('10-May-2014','20-Dec-2014')
and then checked the value of Flag.

MySQL timestamp modification, addition, and comparison

I am creating a view that involves a little bit of fiddling with timestamps.
I have a table A with timestamps. The view will process the timestamps to see if each timestamp is within a certain range (9 AM - 5 PM). If the timestamp is within that range, I will fetch data matching the exact time in another table (B). Otherwise, I will fetch the next day (or this day's) first valid time (which is 9 AM) and the corresponding data from there.
Examples:
A record with timestamp of 12/28/2012 17:01 -> fetch data from B
for 12/29/2012 09:00, set flag to after.
A record with timestamp of 12/28/2012 08:59 -> fetch data from B
for 12/28/2012 09:00, set flag to before.
A record with timestamp of 12/28/2012 09:55 -> fetch data from B
for 12/28/2012 09:55, set flag to null.
Here is what I have so far (not working, some in pseudocode). I mainly don't know how to set the flag based on the comparison and then, based on flag, perform next operation on b - all in one statement.
CREATE VIEW C as
SELECT time, (CASE WHEN (time< '9:00' ) THEN'before'
CASE WHEN(time> '17:00') THEN'after' else null END) AS flag FROM A
//These two should be combined into one create view statement
//The below is utterly wrong, I know, but explains what I mean
SELECT(
CASE WHEN (flag=='before') THEN SELECT * FROM B WHERE B.time = time set hour='9:00'
CASE WHEN(flag=='after') THEN SELECT* FROM B WHERE B.time = time + one day set hour='9:00'
ELSE SELECT* FROM B WHERE B.time = time ) as data
Tested using this fiddle: http://sqlfiddle.com/#!2/15be5/50
SELECT
q.time as original_time_check,
q.flag as flag_check,
case q.flag
when 'before' then q.NINE_AM_ON_THE_DAY
when 'after' then q.NINE_AM_THE_NEXT_DAY
else q.time
end as time
FROM
(
SELECT
time,
date(time) + INTERVAL 9 HOUR as NINE_AM_ON_THE_DAY,
date(time) + INTERVAL '1 9' DAY_HOUR as NINE_AM_THE_NEXT_DAY,
case
when time < (date(time) + INTERVAL 9 HOUR) then 'before'
when time < (date(time) + INTERVAL 17 HOUR) then 'in-range'
else 'after'
end as flag
FROM
Your_table
) q

How to get data back from Mysql for days that have no statistics

I want to get the number of Registrations back from a time period (say a week), which isn't that hard to do, but I was wondering if it is in anyway possible to in MySQL to return a zero for days that have no registrations.
An example:
DATA:
ID_Profile datCreate
1 2009-02-25 16:45:58
2 2009-02-25 16:45:58
3 2009-02-25 16:45:58
4 2009-02-26 10:23:39
5 2009-02-27 15:07:56
6 2009-03-05 11:57:30
SQL:
SELECT
DAY(datCreate) as RegistrationDate,
COUNT(ID_Profile) as NumberOfRegistrations
FROM tbl_profile
WHERE DATE(datCreate) > DATE_SUB(CURDATE(),INTERVAL 9 DAY)
GROUP BY RegistrationDate
ORDER BY datCreate ASC;
In this case the result would be:
RegistrationDate NumberOfRegistrations
25 3
26 1
27 1
5 1
Obviously I'm missing a couple of days in between. Currently I'm solving this in my php code, but I was wondering if MySQL has any way to automatically return 0 for the missing days/rows. This would be the desired result:
RegistrationDate NumberOfRegistrations
25 3
26 1
27 1
28 0
1 0
2 0
3 0
4 0
5 1
This way we can use MySQL to solve any problems concerning the number of days in a month instead of relying on php code to calculate for each month how many days there are, since MySQL has this functionality build in.
Thanks in advance
No, but one workaround would be to create a single-column table with a date primary key, preloaded with dates for each day. You'd have dates from your earliest starting point right through to some far off future.
Now, you can LEFT JOIN your statistical data against it - then you'll get nulls for those days with no data. If you really want a zero rather than null, use IFNULL(colname, 0)
Thanks to Paul Dixon I found the solution. Anyone interested in how I solved this read on:
First create a stored procedure I found somewhere to populate a table with all dates from this year.
CREATE Table calendar(dt date not null);
CREATE PROCEDURE sp_calendar(IN start_date DATE, IN end_date DATE, OUT result_text TEXT)
BEGIN
SET #begin = 'INSERT INTO calendar(dt) VALUES ';
SET #date = start_date;
SET #max = SUBDATE(end_date, INTERVAL 1 DAY);
SET #temp = '';
REPEAT
SET #temp = concat(#temp, '(''', #date, '''), ');
SET #date = ADDDATE(#date, INTERVAL 1 DAY);
UNTIL #date > #max
END REPEAT;
SET #temp = concat(#temp, '(''', #date, ''')');
SET result_text = concat(#begin, #temp);
END
call sp_calendar('2009-01-01', '2010-01-01', #z);
select #z;
Then change the query to add the left join:
SELECT
DAY(dt) as RegistrationDate,
COUNT(ID_Profile) as NumberOfRegistrations
FROM calendar
LEFT JOIN
tbl_profile ON calendar.dt = tbl_profile.datCreate
WHERE dt BETWEEN DATE_SUB(CURDATE(),INTERVAL 6 DAY) AND CURDATE()
GROUP BY RegistrationDate
ORDER BY dt ASC
And we're done.
Thanks all for the quick replies and solution.