mysql query to select between previous and next month - mysql

Trying to select all days from the start of the previous month to the end of the next month:
USE test;
SELECT * FROM MyTable
WHERE col_date BETWEEN DATE_ADD(DATE_ADD(NOW(), INTERVAL -1 MONTH))
AND DATE_ADD(DATE_ADD(NOW(), INTERVAL +1 MONTH))
Its saying my syntax in incorrect, but I saw snippet of the DATE_ADD function being used like this.

You can use date_sub()
date_sub(now(), INTERVAL 1 MONTH)
So the query should be something as
USE test;
SELECT * FROM MyTable
WHERE
col_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND DATE_ADD(NOW(), INTERVAL 1 MONTH)
Here how it looks like in mysql
mysql> select date_sub(now(), INTERVAL 1 MONTH) as previous_month , date_add(now(),INTERVAL 1 MONTH) as next_month;
+---------------------+---------------------+
| previous_month | next_month |
+---------------------+---------------------+
| 2014-05-06 22:27:35 | 2014-07-06 22:27:35 |
+---------------------+---------------------+
1 row in set (0.01 sec)
mysql> select NOW() - INTERVAL 1 MONTH as previous_month ,NOW() + INTERVAL 1 MONTH as next_month ;
+---------------------+---------------------+
| previous_month | next_month |
+---------------------+---------------------+
| 2014-05-06 22:28:39 | 2014-07-06 22:28:39 |
+---------------------+---------------------+

Related

Extract last working day of every month in bigquery

Currently I'm using the below code:
SELECT DATE_SUB(example, INTERVAL 1 DAY) ,
FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY))
FROM UNNEST(GENERATE_DATE_ARRAY('2013-01-1', '2030-04-01', INTERVAL 3 MONTH)) AS example
The output which I'm getting is:
2012-12-31 Monday
2013-03-31 Sunday
2013-06-30 Sunday
2013-09-30 Monday
2013-12-31 Tuesday
2014-03-31 Monday
2014-06-30 Monday
2014-09-30 Tuesday
The expected output is:
2012-12-31 Monday
2013-03-29 Friday
2013-06-28 Friday
2013-09-30 Monday
2013-12-31 Tuesday
2014-03-31 Monday
2014-06-30 Monday
2014-09-30 Tuesday
I'm trying to extract the last working day for each quarter(3 months of timegap). But i couldn't exclude saturdays and sundays.
It would be great if someone help me to sort out this issue.
try this.
SELECT case when FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY)) = 'Sunday'
then date_sub(DATE_SUB(example, INTERVAL 1 DAY), interval 2 day)
when FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY)) = 'Saturday'
then date_sub(DATE_SUB(example, INTERVAL 1 DAY), interval 1 day)
else DATE_SUB(example, INTERVAL 1 DAY) end as d1,
case when FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY)) in ('Saturday','Sunday')
then 'Friday'
else FORMAT_DATE("%A", DATE_SUB(example, INTERVAL 1 DAY)) end
FROM UNNEST(GENERATE_DATE_ARRAY('2013-01-1', '2030-04-01', INTERVAL 3 MONTH)) AS example
order by d1
Try using this in your query ORDER BY your_date ASC
Consider below approach
create temp function getLastBusinessDayOfMonth(next_month_first_day date) as ((
select as struct month_last_business_day,
format_date("%A", month_last_business_day) day_of_week
from unnest([struct(next_month_first_day - 1 as month_last_day, extract(dayofweek from next_month_first_day) as adjust)]),
unnest([struct(month_last_day - if(adjust > 2, 0, adjust) as month_last_business_day)])
));
select getLastBusinessDayOfMonth(sample).*
from unnest(generate_date_array('2013-01-1', '2014-11-01', interval 3 month)) as sample
with output
You also can calculate the diffenece to the last workday with ELT().
This function returns the difference, in days, to the last workday
ELT(dayofweek(example), '2','3','1','1','1','1','1')
Sample for MariaDB
SELECT
example as org
, example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY AS LAST_WORKDAY
, DATE_FORMAT(example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY,'%W') AS WEEKDAY
FROM (
SELECT date('2013-01-01') + interval seq MONTH as example from seq_0_to_4) as d;
Sample for MySQL
SELECT
example as org
, example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY AS LAST_WORKDAY
, DATE_FORMAT(example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY,'%W') AS WEEKDAY
FROM UNNEST(GENERATE_DATE_ARRAY('2013-01-1', '2030-04-01', INTERVAL 3 MONTH)) AS example;
Result
MariaDB [bernd]> SELECT
-> example as org
-> , example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY AS LAST_WORKDAY
-> , DATE_FORMAT(example - INTERVAL ELT(dayofweek(example), '2','3','1','1','1','1','1') DAY,'%W') AS WEEKDAY
-> FROM (
-> SELECT date('2013-01-01') + interval seq MONTH as example from seq_0_to_4) as d ;
+------------+--------------+----------+
| org | LAST_WORKDAY | WEEKDAY |
+------------+--------------+----------+
| 2013-01-01 | 2012-12-31 | Monday |
| 2013-02-01 | 2013-01-31 | Thursday |
| 2013-03-01 | 2013-02-28 | Thursday |
| 2013-04-01 | 2013-03-29 | Friday |
| 2013-05-01 | 2013-04-30 | Tuesday |
+------------+--------------+----------+
5 rows in set (0.001 sec)
MariaDB [bernd]>

how may i select the time interval from last month ?, and it must also be between 1pm from last day of the last month till midday of the actual day

I've been trying to solve this problem for a few hours , so far what i have reached is something like this:
SELECT * FROM mytable WHERE DATE(datetime_column)
BETWEEN DATE_SUB(DATE_FORMAT(NOW(),'%Y-%M-01'),INTERVAL 1 DAY) AND NOW()
AND HOUR(datetime_column) > = '13'
ORDER BY
datetime_column
Besides the day interval, i also need the hour interval which must be between 13h pm from last day of the last month till midday for present date.
The fiddle doesnt seem to work with the current query but its working in my database, but check fiddle for more info:
https://www.db-fiddle.com/f/a3jui7aPMevU81Cka4BqXg/0
And sample data:
CREATE TABLE mytable (
id INT,
datetime_column DATETIME
);
INSERT INTO mytable (id,datetime_column) VALUES
(1,'2020-03-31 08:00:00'),
(2,'2020-03-31 13:00:00'),
(3,'2020-04-02 14:30:00'),
(4,'2020-04-06 18:00:00'),
(5,'2020-04-21 05:00:00'),
(6,'2020-04-23 13:00:00'),
(7,'2020-04-23 14:00:00');
If more info is necessary please let me know.
I think this what you want
SELECT * FROM mytable
WHERE (
DATE(datetime_column) > LAST_DAY(CURDATE() - INTERVAL 1 MONTH)
AND datetime_column < (CURDATE() + INTERVAL 12 HOUR)
)
OR (
DATE(datetime_column) = LAST_DAY(CURDATE() - INTERVAL 1 MONTH)
AND HOUR(datetime_column) >= 13
);
+------+---------------------+
| id | datetime_column |
+------+---------------------+
| 2 | 2020-03-31 13:00:00 |
| 3 | 2020-04-02 14:30:00 |
| 4 | 2020-04-06 18:00:00 |
| 5 | 2020-04-21 05:00:00 |
+------+---------------------+
2 rows in set (0.00 sec)
Here LAST_DAY(CURDATE() - INTERVAL 1 MONTH) gives the last day of previous month.
And datetime_column < (CURDATE() + INTERVAL 12 HOUR) tests if that time is before mid day of today.

finding a specific date in MySql

I knew this will give syntax error.
SELECT DATE_SUB(DATE_SUB(now(),INTERVAL 3 MONTH)),INTERVAL EXTRACT(DAY FROM (DATE_SUB(now(),INTERVAL 3 MONTH))) DAY) as oldDate
I am new to SQL and in here I am trying to find 3 month old date and the first day of that month.
for example 3 month old date from today will be 28-11-2014 so I have to show 01-11-2014.
so how to sort above code to avoid syntax error.
You can use DATE_FORMAT to format the date according to your requirements.
SELECT DATE_SUB(NOW(), INTERVAL 3 MONTH) 3months_ago,
DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 3 MONTH), "01-%m-%Y") first_day
FROM DUAL
+---------------------+------------+
| 3months_ago | first_day |
+---------------------+------------+
| 2014-11-28 09:20:50 | 01-11-2014 |
+---------------------+------------+
You can use date_format() function along with date_sub() to get the 1st day of month
mysql> select date_format(date_sub(curdate(),interval 3 month),'01-%m-%Y') ;
+--------------------------------------------------------------+
| date_format(date_sub(curdate(),interval 3 month),'01-%m-%Y') |
+--------------------------------------------------------------+
| 01-11-2014 |
+--------------------------------------------------------------+

MySQL select data from last week

I was wondering how to select all the data from last week? Between Monday to Friday, assuming that today is a Monday. I actually don't have a datetime format column.
Here's what I tried so far:
SELECT * FROM logs
WHERE WEEKDAY(CONCAT(year,'-',month,'-',day)) BETWEEN 0 AND 4
AND YEARWEEK( date_added2 ) = YEARWEEK( CURRENT_DATE( ) - INTERVAL 7 DAY) AND deleted='n';
And this is my table, table logs:
Could you try this? you can test here http://www.sqlfiddle.com/#!2/3989b1/3/0
SELECT *
FROM logs,
(SELECT (CURRENT_DATE() - INTERVAL (WEEKDAY(CURRENT_DATE()) + 1 ) % 7 DAY) AS sun_day) t1
WHERE
logs.date_added2 BETWEEN t1.sun_day - INTERVAL 6 DAY
AND t1.sun_day - INTERVAL 2 DAY;
How it works
folling query returns sunday of week
SELECT '2014-01-09' - INTERVAL (WEEKDAY('2014-01-09') + 1 ) % 7 DAY;
+--------------------------------------------------------------+
| '2014-01-09' - INTERVAL (WEEKDAY('2014-01-09') + 1 ) % 7 DAY |
+--------------------------------------------------------------+
| 2014-01-05 |
+--------------------------------------------------------------+
SELECT '2014-01-10' - INTERVAL (WEEKDAY('2014-01-10') + 1 ) % 7 DAY;
+--------------------------------------------------------------+
| '2014-01-10' - INTERVAL (WEEKDAY('2014-01-10') + 1 ) % 7 DAY |
+--------------------------------------------------------------+
| 2014-01-05 |
+--------------------------------------------------------------+
so, t1.sun_day - INTERVAL 6 holds monday of previous week, and t1.sun_day - INTERVAL 2 DAY for friday of previous week.
mysql> SELECT #sunday := (CURRENT_DATE() - INTERVAL (WEEKDAY(CURRENT_DATE()) + 1 ) % 7 DAY) AS sunday;
+------------+
| sunday |
+------------+
| 2014-01-05 |
+------------+
mysql> SELECT #sunday - INTERVAL 6 DAY, #sunday - INTERVAL 2 DAY;
+--------------------------+---------------------------+
| #sunday - INTERVAL 6 DAY | #sunday - INTERVAL 2 DAY |
+--------------------------+---------------------------+
| 2013-12-30 | 2014-01-03 |
+--------------------------+---------------------------+
So, logs.date_added2 BETWEEN t1.sun_day - INTERVAL 6 DAY AND t1.sun_day - INTERVAL 2 DAY would find logs from monday to friday.

MySQL: DATE_ADD

Is there a difference between:
SELECT DATE_ADD('2005-01-01', INTERVAL 3 MONTH);
and
SELECT '2005-01-01' + INTERVAL 3 MONTH;
No, they're the same.
I asked a similar question just now and found the answer myself. Here's the justification why they are the same:
SELECT BENCHMARK(20000000, DATE_ADD(NOW(), INTERVAL 3 MONTH));
+--------------------------------------------------------+
| BENCHMARK(20000000, DATE_ADD(NOW(), INTERVAL 3 MONTH)) |
+--------------------------------------------------------+
| 0 |
+--------------------------------------------------------+
1 row in set (1.70 sec)
SELECT BENCHMARK(20000000, NOW() + INTERVAL 3 MONTH);
+-----------------------------------------------+
| BENCHMARK(20000000, NOW() + INTERVAL 3 MONTH) |
+-----------------------------------------------+
| 0 |
+-----------------------------------------------+
1 row in set (1.71 sec)