i would like someone to help me with this query to convert it on sequelize, i tried but without success.
SELECT id,name,startdate FROM ?? where DATE(startdate) = curdate() + interval 1 day order by ut desc;
My approach:
where: models.Sequelize.where(models.Sequelize.fn('DATE', models.Sequelize.col('startdate')), models.Sequelize.fn('curdate'), '+ interval 1 day'),
attributes: ['name', 'startdate']
Error that i face is here
Executing (default): SELECT `name`, `startdate` FROM `event` AS `event` WHERE DATE(`startdate`) [object Object] '+ interval 1 day';
if i try without this ,'+ interval 1 day' on this approach models.Sequelize.where(models.Sequelize.fn('DATE', models.Sequelize.col('startdate')), models.Sequelize.fn('curdate')
it works but i need to add a interval.
Just change .fn :
models.Sequelize.fn('curdate'), '+ interval 1 day')
to .literal :
models.sequelize.literal('curdate() + interval 1 day')
Related
If I use the Following code in PHPMyAdmin (SQL) statement, it works and I get a list of all Birthdays of the following 31 days. Here is my code:
SELECT
*
FROM
membres
WHERE
DATE_ADD(
date_de_naissance,
INTERVAL
YEAR(CURDATE()) -
YEAR(date_de_naissance) +
IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(date_de_naissance), 1, 0)
YEAR
)
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 31 DAY)
AND
(
MONTH(date_de_naissance) <> MONTH(CURDATE())
OR
DAY(date_de_naissance) <> DAY(CURDATE())
)
How would it be in Cakephp? Please help
I generally find it's much easier to do the date math in CakePHP than in MySQLs, so I'd do something like this:
$birthday_members = $this->Membres->find()
->where([
'date_de_naissance >' => Cake\I18n\FrozenDate::now(),
'date_de_naissance <=' => Cake\I18n\FrozenDate::now()->addDays(31),
]);
I want to add 5 days to the provided date, but the calculation must skip weekends.
I already know how to add 5 days without skipping weekends:
SELECT DATE_ADD(`date_field`, INTERVAL 5 DAY) As FinalDate
FROM `table_name`;
Now I want the returned value to skip weekends.
Currently if date_field = 2016-07-22 the results will be 2016-07-27
But I want the results to be 2016-07-29
Try this:
SELECT DATE_ADD(
date_field,
INTERVAL 5 +
IF(
(WEEK(date_field) <> WEEK(DATE_ADD(date_field, INTERVAL 5 DAY)))
OR (WEEKDAY(DATE_ADD(date_field, INTERVAL 5 DAY)) IN (5, 6)),
2,
0)
DAY
) AS FinalDate
FROM `table_name`;
How it works:
Firstly, it will add 5 days on your date.
Secondly, when date_field and 5 days later are in two different weeks, it must be added additional 2 days.
Thirdly, when 5 days later is Sat or Sun, it must be added additional 2 days.
This can easily be done for an arbitrary amount of days with a recursive CTE:
WITH RECURSIVE a AS (
SELECT
CURRENT_DATE date, -- Start date
0 days
UNION
SELECT
-- Always increment the date
a.date + INTERVAL 1 DAY AS date,
-- Increment the work day count only if it's not a weekend day
a.days + (WEEKDAY(a.date + INTERVAL 1 DAY) < 5) AS days
FROM a
WHERE
-- Keep going until the week day count reaches 10
a.days < 10 -- Amount of days to add
)
SELECT MAX(date)
FROM a
In the example situation you would use a subquery:
SELECT
(
WITH RECURSIVE a AS (
SELECT
date_field date,
0 days
UNION
SELECT
a.date + INTERVAL 1 DAY AS date,
a.days + (WEEKDAY(a.date + INTERVAL 1 DAY) < 5) AS days
FROM a
WHERE a.days < 5
)
SELECT MAX(date)
FROM a
) AS final_date
FROM table_name
I did try your solution but faced a problem when using it with a larger interval (e.g 20 days). It works perfectly with little intervals though.
Example : for '2017-10-04' + 20 days, your algorithm return '2017-10-26'. It should be '2017-11-01' since we skip 4 weekends.
The numbers of days you add isn't calculated depending on the difference between the 2 week #, so the maximum days you can add is 2 and in my case, it should be 8 (4x2).
I modified your code to end up with this (I also add variables, much more convenient to modify)
SELECT
#ID:='2017-10-04' as initial_date, -- the initial date in the right format to manipulate (add x day)
#DTA:=20 as days_to_add, -- number of days to add
#DA:= DATE_ADD(#ID, INTERVAL #DTA DAY) as date_add,
#LASTDAY := WEEKDAY(#DA) as last_day, -- the day (Monday, Tuesday...) corresponding to the initial date + number of days to add
#WEEK1 := DATE_FORMAT(#ID, '%v') as initial_date_week, -- format the initial date to match week mode 3 (Monday 1-53)
#WEEK2 := DATE_FORMAT(#DA, '%v') as added_date_week_nbr, -- the week # of the initial_date + number of days to add
#WEEKDIFF := #WEEK2 - #WEEK1 as week_difference, -- the difference between week 2 and week 1
DATE_ADD(#ID,
INTERVAL #DTA +
if ( #WEEKDIFF > 0 or #LASTDAY in (5,6),
2,
0
) +
if (#WEEKDIFF > 1,
#WEEKDIFF*2,
0
) DAY
) AS FinalDate
The way I get my week numbers can seems weird but this is because I'm running this in France and my DB seems to be configured in a way that weeks are natively starting by Sunday, "%v" represent the 'mode 3' for weeks, you can check the MySQL documentation here for more details : https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html (ctrl + F > '%v')
I didn't implement the public holiday yet, but I'm thinking of adding X days in the calculation each times one of this day is in the period we're looking at.
According to my (few) tests, this should work. Let me know if not
try this out, should work nicely, basically loop through each of the days and check if they are saturday or sunday, ignore them.
https://social.technet.microsoft.com/wiki/contents/articles/30877.t-sql-extending-dateadd-function-to-skip-weekend-days.aspx
Plus hollydays 1 or 2
select GREATEST(WEEKDAY(NOW()) - 4, 0) 'hollydays'
My solution is to create a function that returns the calculated date, it will consider the consecutive weekends:
DELIMITER $$
CREATE FUNCTION `add_working_days_to_current_month`(ndays INT) RETURNS DATE
NO SQL
BEGIN
declare finalDate, startDate, originalFinalDate DATE;
declare weekNumberStartDate, weekNumberEndDate, weekDiff INT;
set startDate = DATE(CONCAT(YEAR(DATE_SUB(current_date(), INTERVAL 1 MONTH)),"-",MONTH(DATE_SUB(current_date(), INTERVAL 1 MONTH)),"-",DAY(LAST_DAY(DATE_SUB(current_date(), INTERVAL 1 MONTH)))));
set weekNumberStartDate = WEEK(startDate);
set finalDate = DATE_ADD(startDate, INTERVAL ndays DAY);
set originalFinalDate = finalDate;
set weekNumberEndDate = WEEK(finalDate);
IF(weekNumberEndDate != weekNumberStartDate) THEN
set weekDiff = (weekNumberEndDate - weekNumberStartDate) * 2;
set finalDate = DATE_ADD(finalDate, INTERVAL weekDiff DAY);
END IF;
set weekNumberStartDate = WEEK(originalFinalDate);
set weekNumberEndDate = WEEK(finalDate);
IF(weekNumberEndDate != weekNumberStartDate) THEN
set weekDiff = (weekNumberEndDate - weekNumberStartDate) * 2;
set finalDate = DATE_ADD(finalDate, INTERVAL weekDiff DAY);
END IF;
IF(WEEKDAY(finalDate) IN (5, 6)) THEN
set finalDate = DATE_ADD(finalDate, INTERVAL 2 DAY);
END IF;
return finalDate;
END$$
DELIMITER ;
Basically i'm using the same logic as the accepted answer but acumulating the weekends. So for each weekend i will add 2 days and at the end i will if the result date is on weekend i will add 2 more
WHERE datefield BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL 7 DAY
AND WEEKDAY(datefield) NOT IN (5,6);
I am trying to select all data from my table where condition is
performDate will be between today 2.00 AM to tomorrow 2.00 AM
My query gives this error
Incorrect parameter count in the call to native function 'DATEDIFF'
My query is
SELECT * FROM `admin_marker` WHERE
FROM_UNIXTIME(performDate)
BETWEEN DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) + '02:00'
AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()+1), 0) + '02:00'
DATEDIFF expects only 2 parameters. You call it with 3 parameter.
Why dont you do it that way ?
WHERE performdate >= DATE_FORMAT(NOW(), '%Y-%m-%d 02:00:00') AND performdate <= DATE_FORMAT(CURRENTDATE + INTERVAL +1 DAY '%Y-%m-%d 02:00:00')
I working on a financial project where i need to calculate the difference of arrear days. If I use the method datediff() of mysql then it returns the result based on 365 days. I need the result based on 360 days. if use the following sql query
select datediff('20140908','20130908') from dual;
mysql returns the date difference 365. This is the actual date difference but in accounting/Financial calculation the difference is exactly one year (360 days). This is what I want. The result should be 360 instead 365.
Currently I want to use US standard.
to get the same result like Excel, I found the following code to use in MySQL:
select case
when (day(Startdate)>=30 or Startdate=last_day(Startdate) then
case
when(day(Enddate)>=30) then
30*(12*(year(Enddate)-year(Startdate))+month(Enddate)-month(Startdate))
else
30*(12*(year(Enddate)-year(Startdate))+month(Enddate)-month(Startdate))+days(Enddate)-30
end
else
30*(12*(year(Enddate)-year(Startdate))+month(Enddate)-month(Startdate))+days(Enddate)-days(Startdate)
end
Use
TO_DAYS(date2) - To_DAYS(date1)
It returns the number of days between date1 and date2. Then you can do with the result what you need.
sdate = from date
edate = to date
this calculate the days between the 2 date, taking into account that a month is 30 days, 1 year is 360 days, and checking if the date are at the end of the month, so e.g. from 1.1.2019 to 28.2.2019 = 60 days etc.
to be 1 month or 1 year, the edate should be a day before, so 1.1 - 31.1 = 30 days, 1.1 - 1.2 = 31 days
SELECT GREATEST(
0,
(YEAR(DATE_ADD(edate, INTERVAL 1 DAY)) - YEAR(sdate)) * 360 +
(MONTH(DATE_ADD(edate, INTERVAL 1 DAY)) - MONTH(sdate)) * 30 +
(
IF(DAYOFMONTH(DATE_ADD(edate, INTERVAL 1 DAY)) = DAYOFMONTH(LAST_DAY(DATE_ADD(edate, INTERVAL 1 DAY))), 30, DAYOFMONTH(DATE_ADD(edate, INTERVAL 1 DAY))) -
IF(DAYOFMONTH(sdate) = DAYOFMONTH(LAST_DAY(sdate)), 30, DAYOFMONTH(sdate))
)
Pretty late here, but posting my solution for future reference
CREATE FUNCTION `DAYS360_UDF`(sdate DATE, edate DATE)
RETURNS INTEGER
DETERMINISTIC
CONTAINS SQL
BEGIN
DECLARE sdate_360 INTEGER;
DECLARE edate_360 INTEGER;
SET sdate_360 = ( YEAR(sdate) * 360 ) + ( (MONTH(sdate)-1)*30 ) + DAY(sdate);
SET edate_360 = ( YEAR(edate) * 360 ) + ( (MONTH(edate)-1)*30 ) + DAY(edate);
RETURN edate_360 - sdate_360;
END
Usage -
select DAYS360_UDF('20130908', '20140908')
i have a table with a time field and i need to add an int field to it.
here's the line of code (it's a piece of a trigger.)
DECLARE duration Int;
[....]
SET NEW.appointmentEnd = NEW.appointmentTime + duration;
This works until the time gets to a full hour. So 8:30:00 + 1500 = 8:45:00 But 8:30:00 + 3000 = 0:00:00.
How to fix this?
Thanks in advance! :)
Instead of adding a "plain" int, you should be adding anexplicit interval:
new.appointmenttime = (new.appointmenttime + INTERVAL durationInMinutes MINUTE)
You are not limited to using MINUTE, of course: you can use SECOND if you need more precision.
MySQL doesn't do direct date/time math by adding what you are trying of "seconds". But you can do via Date_Add() and Date_Sub() such as
set appointmentEnd = date_Add( appointmentTime, interval 15 minutes )
You should use date arithmetic, like:
mysql> SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
-> '2009-01-01 00:00:00'
Or
mysql> SELECT DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY);
-> '2011-01-01 23:59:59'
So if duration is, for example, in seconds:
SET NEW.appointmentEnd = NEW.appointmentTime + INTERVAL duration SECOND;