Finding the date one month in advance on the same day - mysql

In MySQL, I can do something like:
SELECT DATE_ADD('2010-07-02', INTERVAL 1 MONTH)
And that returns:
2010-08-02
That's great... now is there a MySQL function that I can use to find what the date would be one month in advance on the same day. For example, 7/2/2010 falls on the first Friday of July, 2010. Is there an easy way to find what the first Friday of August, 2010 is with an SQL statement?

It got a bit complicated, but here goes:
SELECT IF(MONTH(DATE_ADD('2010-07-02', INTERVAL 28 DAY)) = MONTH('2010-07-02'),
DATE_ADD('2010-07-02', INTERVAL 35 DAY),
DATE_ADD('2010-07-02', INTERVAL 28 DAY));
Rationale: If you add 4 weeks or 5 weeks, you're still on the same day; since all months are between 28 and 35 days long, if 4 weeks later is still the same month, add another week.
UPDATE: Umm, I did not think this through very well - it works for first X in month, but necessarily for 2nd, 3rd... (i.e. 3rd X in month might return a 2nd X next month). Try #2:
SELECT IF(
CEIL(DAY(DATE_ADD('2010-07-02', INTERVAL 35 DAY)) / 7) = CEIL(DAY('2010-07-02') / 7),
DATE_ADD('2010-07-02', INTERVAL 35 DAY),
DATE_ADD('2010-07-02', INTERVAL 28 DAY));
Rationale: CEIL(DAY(x) / 7) is x's week number. If it's different when you add 5 weeks, then add 4 weeks.
UPDATE 2: LOL, I suck today, I should really think before I post... Week is usually defined as Mon-Sun, or Sun-Mon, not as from whatever started the month till 6 days later. To compensate for this:
SELECT IF(
CEIL((DAY(DATE_ADD('2010-07-02', INTERVAL 28 DAY)) - DAYOFWEEK('2010-07-02')) / 7)
= CEIL((DAY('2010-07-02') - DAYOFWEEK('2010-07-02')) / 7),
DATE_ADD('2010-07-02', INTERVAL 28 DAY),
DATE_ADD('2010-07-02', INTERVAL 35 DAY));

Does this do the trick?
SELECT DATE_ADD(
DATE_SUB(
DATE_ADD('2010-07-06', INTERVAL 1 MONTH),
INTERVAL DAYOFWEEK(DATE_ADD('2010-07-06', INTERVAL 1 MONTH)) DAY
),
INTERVAL DAYOFWEEK('2010-07-06') DAY
)

Related

Select data starting from last Sunday at 8 PM

I'm trying to select all rows that have a date greater than or equal to the previous Sunday at 8 PM. So, if it were 7 PM on a Sunday right now, the selection would contain almost a full week of data. And if it were 9 PM on a Sunday right now, the selection would contain about an hour's worth of data.
So the following query isn't what I'm interested in, because it doesn't start and end on Sunday at 8 PM.
SELECT * FROM table WHERE date >= DATE_SUB(NOW(), INTERVAL 1 WEEK)
I'm not sure how to do write the correct query though.
You can use the cast statement to tweak the logic when your criteria matches.
Change the time Interval accordingly. I didn't added seconds so both the conditions will take 8 PM data.
SELECT * FROM table
WHERE date >= select CASE WHEN (DAYOFWEEK(NOW()) = 1 AND CURTIME() >= '20:00:00') THEN DATE(NOW()) + INTERVAL 20 HOUR
WHEN (DAYOFWEEK(NOW()) = 1 AND CURTIME() <= '20:00:00') THEN DATE_ADD(DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())+6 DAY), interval 20 hour)
ELSE DATE_ADD(DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY), interval 20 hour) END

Get records from last one year upto last date of previous month in mysql

I am trying to get records from last one year and upto last date of provious month i.e. not including the current month. Here's my query:
SELECT `customer_id`, `customer_name`, `customer_date`
FROM `customers`
WHERE DATE(`customer_date`) <= (CURDATE() - INTERVAL 1 MONTH)
AND DATE(customer_date) >= (CURDATE() - INTERVAL 12 MONTH)
This query fetches records from 1 May, 2018 to 8 April 2019.
INTERVAL 1 MONTH fetches records 30 days ago. What I need to do something here?
I want to exclude current month records, so query should return records upto 30 April 2019. How do we do that?
You must correctly calculate the first and last days of range with help LAST_DAY() function. For example:
Calculate the first day of the range
SELECT LAST_DAY(CURDATE() - INTERVAL 13 MONTH) + INTERVAL 1 DAY
Output:
2018-05-01
Calculate last day of the range
SELECT LAST_DAY(CURDATE() - INTERVAL 1 MONTH)
Output:
2019-04-30
The full query might look like:
SELECT `customer_id`, `customer_name`, `customer_date`
FROM `customers`
WHERE `customer_date` >= LAST_DAY(CURDATE() - INTERVAL 13 MONTH) + INTERVAL 1 DAY
AND `customer_date` <= SELECT LAST_DAY(CURDATE() - INTERVAL 1 MONTH)
To get data up to the previous month:
where customer_date < curdate() + interval (1 - day(curdate()) day
Why? First note that there is no function call on the customer_date. So, this expression is index-compatible and can use an index.
Second, this structure works both for dates and date/times. That is very handy, because it may not always be obvious if a column has a time component (people are not very good about naming columns to capture this information).
You claim that the "12 months" ago portion works. That doesn't look correct to me. For the complete logic:
where customer_date < curdate() + interval (1 - day(curdate()) day and
customer_date >= (curdate() + interval (1 - day(curdate()) day) - interval 1 year)
SELECT `customer_id`, `customer_name`, `customer_date` FROM `customers` WHERE
MONTH(`customer_date`) <= (CURDATE() - INTERVAL 1 MONTH) AND
MONTH(customer_date) >= (CURDATE() - INTERVAL 12 MONTH)
hope this help

get sql results that have a timestamp date that is n number of days from today

most of the results ive found while looking this up have been from getting a range of dates from today to say 30 days from now. Im just looking for the results that 14, 7, 3 and 1 day from today (each individualy)
Heres the sql i have so far
SELECT * FROM Location WHERE timestamp (CURDATE() + 14 Day)
that would be the sql to get all locations that have a timestamp that is 14 days from now (this is to send out a reminder newsletter fyi).
And it shouldnt matter what time of that day it is, if possible it should grab all timestamp results from that day
SELECT * FROM Location
WHERE DATE(timestamp) IN (
DATE_ADD(CURDATE(), INTERVAL 14 DAY),
DATE_ADD(CURDATE(), INTERVAL 7 DAY),
DATE_ADD(CURDATE(), INTERVAL 3 DAY),
DATE_ADD(CURDATE(), INTERVAL 1 DAY)
);
Reference: MySQL add days to a date

Query data in an specified interval

I am trying to query a timesheet where time span (cycle) is 21 to 20, thus today (10/30/2014) is November.
So, 10/14/2014 is October.
2014-09-21 and 2014-10-20 is one time span
2014-10-21 and 2014-11-20 is one time span
The table is simply storing the date for the timesheet:
id date hours
So, I can specifically say:
SELECT * FROM rapoarte WHERE DATE(ziua) BETWEEN "2014-09-21" AND "2014-10-20"
But I can't figure out how to:
How can I query through this interval for say 1 year (or more)
How can I query for this month?
dynamically
The easiest way is to do date arithmetic. So, for October, you would use:
SELECT *
FROM rapoarte
WHERE month(DATE(ziua) - interval 20 day + interval 1 month) = 10
The idea is to subtract 20 days and add a month. This seems to be the logic for the reporting month.
You can add this as a field:
SELECT *,
date_format(month(DATE(ziua) - interval 20 day + interval 1 month), '%Y-%m') as ReportingMonth
FROM rapoarte
WHERE month(DATE(ziua) - interval 20 day + interval 1 month) = 10
EDIT:
If you want data for this reporting month:
WHERE month(DATE(ziua) - interval 20 day + interval 1 month) = month(DATE(now()) - interval 20 day + interval 1 month) and
year(DATE(ziua) - interval 20 day + interval 1 month) = year(DATE(now()) - interval 20 day + interval 1 month)

how to get the last three months of last year using mysql?

How would I go about retrieving records from the last three months of the previous year? I was thinking it would be:
Date_add(curdate() , interval '-1 2' year_month)
Try this:
WHERE my_date_column BETWEEN
SUBDATE(CURDATE(), INTERVAL DAYOFYEAR(CURDATE()) + 91 DAY) AND
SUBDATE(CURDATE(), INTERVAL DAYOFYEAR(CURDATE()) DAY)
91 is one less than 31 + 30 + 31, because BETWEEN is inclusive.
Note that if your column is a datetime type, you'll need the end value to be the last second of the day:
SUBDATE(SUBDATE(CURDATE(), INTERVAL DAYOFYEAR(CURDATE()) - 1 DAY), INTERVAL 1 SECOND)
See SQLFiddle of these expressions generating correct values.
Assuming you date column is named "date", something like:
SELECT
*
FROM
table
WHERE
YEAR(date) = YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))
AND
MONTH(date) BETWEEN 10 AND 12