I have an event in my mysqli database with is due to reoccur every year, i have set up a query which will create a new event exactly 1 year after the present event finishes.
I am wondering if i can set the new date not to be exactly 1 year from the current date but to the date of a specified day one year on?
for example my the date of my event could be Fri 6th Jan 16 but 1 year on the 6th Jan is a Saturday?
reason being my event is usually held on the first Friday of the year, so using the following query
$sql3 =
mysqli_query($conn,"UPDATE temp_table SET
eventDate = DATE_ADD(eventDate , INTERVAL 1 YEAR)")
or die(mysqli_error($conn,"sql3"));
like i said this will give me a date exactly 1 year to the day from the value of eventDate but it does not guarantee it will be a Friday, can this be modified to ensure it is the date of a Friday one year on?
Many thanks
Luke
Try this:
UPDATE temp_table SET eventDate =
DATE_ADD(DATE_ADD(eventDate,INTERVAL 1 YEAR),
INTERVAL 5 - (DATE_FORMAT(DATE_ADD(eventDate, INTERVAL 1 YEAR),'%w')) DAY);
DATE_FORMAT(date, '%w') returns day of week. 0=Sunday..6=Saturday. 5 is friday.
So, this query adds 5-"'%w' of the next year date" days.
If "'%w' of the next year date" is 5, it adds 0 days, if 4, it adds 1 day, if 6, it adds -1 day etc.
Related
I want to get all records from the last x months from my MySQL server. Using 2 months for example(Not from last 2 months, like last 60 days, but from the entire past month and so on. If actual month is april, I want all records from february and march).
I've tried some queries and the last one is
SELECT id FROM ranking WHERE (end_date BETWEEN DATE_FORMAT(NOW(), '%Y-%m-01') AND DATE_FORMAT(LAST_DAY(NOW() - INTERVAL 2 MONTH), '%Y-%m-%d'))
"end_date" is my date column which is a DATE column "2017-04-07".
That query above just returns nothing and I cant figure out where is the error.
Try this:
SELECT id
FROM ranking
WHERE end_date BETWEEN
DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 3 MONTH)) INTERVAL 1 DAY)
AND LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH));
It calculates dates as like this:
For start date in range, it subtracts 3 months from current date, gets the last day of that month and adds a day in it to get the first day of next month (1st February in our case)
For end date, it subtracts one month from current date and gets the last day of that month (31st March in our case)
Try without convert it to string, And BETWEEN requires min date first.
SELECT id
FROM ranking
WHERE end_date BETWEEN LAST_DAY(CAST(NOW() as date) - INTERVAL 2 MONTH
AND CAST(NOW() as date)
I am trying to display only records two weeks in advance from the current date onwards. starttime is stored as a datetime data type in the database.
I have this,
SELECT id, date_format(starttime, '%d-%m-%Y %H:%i') AS formatted_start, date_format(starttime, '%Y-%m-%d') AS formatted_date,
date_format(endtime, ' %H:%i') AS formatted_end
FROM timedates WHERE user_id = 1 AND `status`='' AND YEARWEEK(formatted_date, 0) IN (YEARWEEK(NOW(), 0),
YEARWEEK(DATE_ADD(NOW(), INTERVAL 2 WEEK), 0))
But I am getting a syntax error YEARWEEK(formatted_date, 0) IN (YEARWEEK(NOW(), 0) AND YEARWEEK(DATE_ADD(NOW()
Could anyone tell me what's wrong with it?
It seems MySQL does not support calculated column in the where clause:
try
SELECT id, date_format(starttime, '%d-%m-%Y %H:%i') AS formatted_start,
date_format(starttime, '%Y-%m-%d') AS formatted_date,
date_format(endtime, ' %H:%i') AS formatted_end
FROM timedates
WHERE user_id = 1 AND `status`='' AND
YEARWEEK(starttime, 0) IN (
YEARWEEK(DATE_ADD(NOW(), INTERVAL 1 WEEK), 0),
YEARWEEK(DATE_ADD(NOW(), INTERVAL 2 WEEK), 0))
use starttime instead of formatted_date
As I said, I see no reason to use YEARWEEK function. You need start date set to today which is CURDATE() and plus 2 weeks period which is DATE_ADD(CURDATE(), INTERVAL 2 WEEK) and then we just check if starttime between those 2 dates.
SELECT id, date_format(starttime, '%d-%m-%Y %H:%i') AS formatted_start,
date_format(starttime, '%Y-%m-%d') AS formatted_date,
date_format(endtime, ' %H:%i') AS formatted_end
FROM timedates
WHERE user_id = 1
AND `status`=''
AND DATE(starttime) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 2 WEEK)
How do you define "two weeks in advance"? Our normal inclination, is to think "within two weeks", which would be to simply before 14 days from now.
WHERE starttime >= NOW()
AND starttime < NOW() + INTERVAL 14 DAY
But the original query is using YEARWEEK function, and the behavior with that is a bit different.
If today is Thursday, May 21, 1015. What is the range of dates that starttime should fall into?
For datetimes right now or in the future, we can just do:
WHERE starttime >= NOW()
(We can do just a > rather than >= if we want to exclude startime values that are an exact match for NOW().
The question is, the bit about "two weeks in advance". Adding 14 days, or 2 weeks, would get us up to Thursday, June 4, 2015. It looks like you might also want to include Friday and Saturday, June 5th and 6th. (Up until Sunday, June th.)
We can use an expression to return "Sunday on or following 14 days from today"
If it's a Sunday, we just use that date. (For convenience, we think of that as adding 0 days). If it's Saturday, we need to add 1 day. If it's a Friday, add 2 days, ... Monday, add 6 days.
Conveniently, the expression 6 - WEEKDAY(NOW()) gives us the number of days we need to add to today's date to get to the next Sunday.
Reference: https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_weekday
We probably want to lop the time off at midnight, we can use the DATE() function to do that.
-- startime values on or after now and before midnight
-- of the first sunday on or after the date two weeks from now
WHERE starttime >= NOW()
AND starttime < DATE(NOW()) + INTERVAL 14+6-WEEKDAY(NOW()) DAY
It's much easier to read and understand what the query is doing when we reference bare columns from the table on one side, and do the gyration and manipulation on the other side. It's also easier to test. And, maybe more importantly, it allows MySQL to make effective use of an "range scan" operation on a suitable index, rather than having to evaluate a function on every row in the table.
If today is '2015-05-21', and what you meant by "two weeks in advance" was up until the second Sunday from now (Sunday, May 31, 2015... 1 week and 3 days from now) just replace the 14 with 7.
Again, it really depends on how you define "two weeks in advance", how you determine what that ending date boundary is. Once you can define that, you can write an expression that returns the value, and just compare to value stored in the starttime column.
I'm having troubles selecting future sessions were the date is 21 days from now. So not between now and 21 days but ONLY sessions that will take place 21 days from this day.
In my table dx_sessions_dates I have a field timestart of type BIGINT where a timestamp is saved (why BIGINT and not TIMESTAMP? -> Not my DB, but can't change it ... ).
My SQL Query is :
SELECT timestart, timefinish, sessionid FROM `dx_sessions_dates` WHERE timestart = UNIX_TIMESTAMP(DATE_ADD(NOW(), INTERVAL 21 DAY))
As you can see I want to select all the sessions where timestart is 21 days from now. 21 days from now should be 15 april 2015.
The query always returns 0 rows ... . While in my table I have a timestart with value = 1429081200 . And when you calculate the date with this you see it's 15 april 2015. Why don't I get any rows back?
The unixtimestamp you calculate is never exactly the moment of the value you stored. You just need the same day.
Try
SELECT timestart, timefinish, sessionid
FROM `dx_sessions_dates`
WHERE date(FROM_UNIXTIME(timestart)) = curdate() + interval 21 DAY
Try using BETWEEN to find any rows that have timestart values anywhere within the 24-hour period that is 21 days from today:
SELECT timestart, timefinish, sessionid
FROM dx_sessions_dates
WHERE timestart BETWEEN UNIX_TIMESTAMP(adddate( curdate(), 21)) AND UNIX_TIMESTAMP(adddate(curdate(), 22))
curdate() returns midnight at the start of today, so 21 days from today is up to 22 days from midnight.
I have a SQL statement set up to grab data from the current calendar week. By default, this grabs data starting on Sunday and ending on Saturday. I was hoping to change this so that the start of the calendar week is Thursday and it ends on Wednesday. Below is my statement:
SELECT *
FROM transactions
WHERE yearweek(transactionDate) = yearweek(now())
ORDER BY transactionDate DESC
Is there a way to modify the yearweek in a way to allow this?
Thanks!
You can take advantage of WEEKDAY() which returns a number representing the day of the week (0 = Monday, 6 = Sunday) and some straightforward maths to rewrite this query.
Subtract the weekday you want the week to start on (in your case 4 = Thursday) from the selected date, add 7 and take the remainder from 7. This will give you the number of days to subtract to get the start of your range.
A similar logic applies to calculate the end date of the range.
SELECT *
FROM transactions
WHERE DATE(transactionDate)
BETWEEN DATE_SUB(DATE(NOW()), INTERVAL (WEEKDAY(NOW()) - 4 + 7) % 7 DAY)
AND DATE_ADD(DATE(NOW()), INTERVAL 6 - (WEEKDAY(NOW()) - 4 + 7) % 7 DAY)
ORDER BY transactionDate DESC;
For a different starting date, substitute the weekday for 4 in the query.
You can specify start day - default is 0 (Sunday).
Just set it to 4 (Thursday):
YEARWEEK(transactionDate, 4)
I am retrieving data from a table and show the total SUM of entries. What I want to do is to show the total SUM of entries made on today's date, yesterday and this month. The table is using the unix timestamp format (e.g. 1351771856 for example).
Currently I am using this line to show todays results:
AND comment_date > UNIX_TIMESTAMP() - 24 * 3600";
but that gives me just the entries for the last 24 hours.
Example: So let's say its Friday, 17:00 PM - it gives me the count from Thursday 17:00 PM to Friday 17:00 PM
What I want is to get the results for
Thursday 00:00:00 - 23:59:59 (yesterday in this case)
the results for today (00:00:00 - 23:59:59)
and last week, results that start on Monday, 00:00:00 until "today" (in this case Friday).
I couldn't find a way in the MySQL documentation to achieve this.
This mysql code should work for you:
// Today
AND DATE(from_unixtime(comment_date)) = CURRENT_DATE
// Yesterday
AND DATE(from_unixtime(comment_date)) = DATE_SUB(CURRENT_DATE,INTERVAL 1 DAY)
// This week
AND YEARWEEK(from_unixtime(comment_date), 1) = YEARWEEK(CURRENT_DATE, 1)
// This month
AND YEAR(from_unixtime(comment_date)) = YEAR(CURRENT_DATE)
AND MONTH(from_unixtime(comment_date)) = MONTH(CURRENT_DATE)
Simply use this:
AND comment_date > date_sub(current_date, interval 1 day)
See my answer here, I think it's quite related.
Pull records from orders table for the current week
Consider getting intimate with MySQL's GROUP BY. You will most likely need to know this if you use MySQL.