DB-Fiddle
CREATE TABLE PaL (
id SERIAL PRIMARY KEY,
event_date DATE
);
INSERT INTO PaL
(event_date)
VALUES
('2020-01-01'),
('2020-02-05'),
('2020-03-20'),
('2020-04-15'),
('2020-05-11'),
('2020-06-18'),
('2020-07-19'),
('2020-12-31');
Expected Result:
first_date_of_the_month first_timestamp_of_the_month
2020-01-01 2020-01-01 00:00:00
2020-02-01 2020-02-01 00:00:00
2020-03-01 2020-03-01 00:00:00
2020-04-01 2020-04-01 00:00:00
2020-05-01 2020-05-01 00:00:00
2020-06-01 2020-06-01 00:00:00
2020-07-01 2020-07-01 00:00:00
2020-12-01 2020-12-01 00:00:00
I want to extract the first date and first timestamp of each event_date in the table.
I am doing this with the below query:
SELECT
DATE_ADD(DATE_ADD(LAST_DAY(pl.event_date), INTERVAL 1 DAY), INTERVAL -1 MONTH) AS first_date_of_the_month,
DATE_FORMAT(DATE_ADD(DATE_ADD(LAST_DAY(pl.event_date), INTERVAL 1 DAY), INTERVAL -1 MONTH), '%Y-%m-%d %H:%i:%s') AS first_timestamp_of_the_month
FROM PaL pl
However, HeidiSQL is somehow interpeting the timestamp as value and not as a TIMESTAMP format.
How do I need to change the query so it displays the result as TIMESTAMP?
SELECT *,
DATE_FORMAT(event_date, '%Y-%m-01') AS first_date_of_the_month,
DATE_FORMAT(event_date, '%Y-%m-01 00:00:00') AS first_timestamp_of_the_month
FROM PaL
HeidiSQL is somehow interpeting the timestamp as value and not as a TIMESTAMP format.
This is client problem.
MySQL's datatype system is soft, i.e. each value is converted to needed datatype according to current datatype context implicitly. But you may use correct final context or excplicit final CAST.
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=21a7d3fccaca1329ef8e1797d366c5a6
You don't have to convert to strings to accomplish this. It is simple enough with basic date functions:
SELECT event_date + interval (1 - day(event_date)) day as first_date_of_the_month,
timestamp(event_date + interval (1 - day(event_date)) day) as first_timestamp_of_the_month
FROM PaL pl;
Here is a db<>fiddle.
Gotta chime in here.... The way I prefer in MySQL, the way that uses the inbuilt LAST_DAY() function, is this:
SELECT LAST_DAY(event_date) + INTERVAL 1 DAY - INTERVAL 1 MONTH
For what it's worth the string constants 2021-03-13 00:00:00 and the shorter 2021-03-13 have precisely the same meaning when used as DATE, DATETIME, or TIMESTAMP values. There's little need for a separate first_timestamp_of_the_month value.
It works in Oracle too. In SQL Server, it's EOMONTH(). postgreSQL, not so much.
Related
I am trying to extract x-days before and after a given date range. I have formulated the query as follows
SELECT a,b,date FROM table.test
WHERE date < "2012-09-07" - INTERVAL 2 DAY
AND date > "2012-09-08" + INTERVAL 2
The other approach which was NOT BETWEEN method also. None of them seems to be giving me right answer. The date is of type varchar(30) DEFAULT NULL within the database
Sample Data
a b date
2 4 2012-09-07
3 2 2012-09-05
5 3 2012-09-08
7 4 2012-09-07
8 5 2012-09-06
9 6 2012-09-07
3 7 2012-09-09
What I am looking for it the following:
a b date
3 2 2012-09-05
3 7 2012-09-09
The date is of type varchar(30) DEFAULT NULL within the database
Go for this:
SELECT a,b,date
FROM table.test
WHERE date < str_to_date('2012-09-07', '%Y-%m-%d') - INTERVAL 2 DAY
OR date > str_to_date('2012-09-08', '%Y-%m-%d') + INTERVAL 2 DAY;
Mainly, the AND needs to replaced by OR. I'd prefer an expicit (date) type conversion as well.
Update: re-reading your question carefully, the statement above might not be the one you are looking for. If Gordon go it right and if you want to use BETWEEN you might go for:
SELECT a,b,date
FROM table.test
WHERE date BETWEEN str_to_date('2012-09-07', '%Y-%m-%d') - INTERVAL 2 DAY AND
str_to_date('2012-09-08', '%Y-%m-%d') + INTERVAL 2 DAY
AND date NOT BETWEEN str_to_date('2012-09-07', '%Y-%m-%d') AND
str_to_date('2012-09-08', '%Y-%m-%d');
This is basically the same.
You just have your comparisons backwards:
SELECT a, b, date
FROM table.test
WHERE (date >= '2012-09-07' - INTERVAL 2 DAY AND
date < '2012-09-07'
) OR
(date > '2012-09-08' AND
date <= '2012-09-08' + INTERVAL 2
);
I'm not sure if you want >/< or >=/<=.
I need to filter a column containing the time and date by a date range.
I just want to see the values which have been recorded for a month from the present day.(from 2016-06-21 to 2016-07-21)
The date format in the Column is YYYY-mm-dd HH:mm:ss
Some of the data in the column looks like this:
2016-07-01 13:38:04
2016-07-01 12:52:41
2016-07-01 12:52:41
2015-05-30 13:04:42
2015-05-30 13:04:42
2016-06-29 10:23:39
2016-06-29 10:23:39
2016-06-29 09:49:43
2015-05-29 09:49:20
2015-05-28 15:05:11
2016-05-28 15:04:46
2016-06-28 15:00:43
2016-05-30 11:33:42
2016-05-30 11:30:53
2015-05-02 09:54:34
You can do:
select t.*
from t
where col >= date_sub(curdate(), interval 1 month);
This should work whether your column is stored as a string or a datetime, because the format is readily converted to a datetime. However, you should use the native types for dates and times, rathe than strings.
Here is somewhat you can use:-
SELECT *
FROM drange_table
Where date_range_column between DATE_SUB(curdate(), interval 1 month) and curdate()
I got a Table which looks like this:
DATE | Number
01-01-16 00:00:00 10
02-01-16 00:00:00 10
03-01-16 00:00:00 11
04-01-16 00:00:00 12
05-01-16 00:00:00 13
....
31-01-16 00:00.00 15
........
29-02-16 00:00:00 18
I got this table for the last few months.
I now want to retrieve the value of the rows, which contain the last day of the previous month and the month before the last month. So for today I would like to retrieve the Value of the 31-1-16 and 29-2-16.
My result should look like:
lastmonth | lastmonth2
18-> Corresponding value to Date: 29-02-16 | 15 -> value for 31-01-16
Would appreciate any help.
Cheers
Here is logic for the last day of this month and the previous month:
select last_day(curdate()) as last_day_of_this_month,
last_day(date_sub(curdate(), interval 1 month)) as last_day_of_prev_month
You can get the last day of any month relative to the current month by changing the "1".
And, I have no idea what date "30-2-16". When describing dates, you should use ISO standard formats. The last day of February 2016 was 2016-02-29.
This is Gordon's code for determining the correct dates plus subqueries to fetch the Number values for those rows:
SELECT
(SELECT Number FROM cc_open_csi_view
WHERE last_day(date_sub(curdate(), interval 1 month)) = date(`DATE`)) as lastmonth,
(SELECT Number FROM cc_open_csi_view
WHERE last_day(date_sub(curdate(), interval 2 month)) = date(`DATE`)) as lastmonth2
FROM DUAL;
Hope that's what you wanted! Works for me in a simple example. I don't know if you need the date() part around DATE but it seemed safest.
SELECT CASE
WHEN last_day(curdate()) = `DATE` THEN number
END as number_last_month,
CASE
WHEN last_day(date_sub(curdate(), interval 1 month)) = `DATE`
THEN number
END as number_last_month2
FROM cc_open_csi_view
I can't test it right now on sqlfiddle.
I've written some SQL to give me a range of dates between two times like so:
select date_add(x.min_date, interval ((t500.id-1) * 30) minute) period
from (
select '2013-08-05T23:00' as min_date, '2013-08-06T01:00' as max_date
) x,
t500
where date_add(x.min_date, interval ((t500.id-1) * 30) minute) <= x.max_date);
Where T500 is a trivial table with column id of 1 to 500 I use for simulating a loop.
Now I expect this to return:
2013-08-05 23:00:00
2013-08-05 23:30:00
2013-08-06 00:00:00
2013-08-06 00:30:00
2013-08-06 01:00:00
and finish there. But instead it carries on until 2013-08-06 23:30:00. I tried different max dates and it always returns dates to the end of the day. Could someone explain what's happening and how to make it stop when I want?
First thing that comes to mind would be casting your date strings into a date format instead of a string for example:
cast('2013-08-05T23:00' as smalldatetime)
Using MySQL
ID Date
001 2010-08-01
002 2010-08-15
003 2010-08-22
...
....
Query
select ID, Date from table where date < curdate + 7;
The above query is not working, it showing error.
How to get date upto nextweek date, I don't want to mentioned the date, it should calculate the systemdate + 7 days.
For Example
Today is 2010-06-30,
So it should take a value upto 2010-07-06
How to make a query for this condition....?
Using the DATE_ADD() function:
... WHERE date < DATE_ADD(CURDATE(), INTERVAL 7 DAY);
using an operator:
.... WHERE date < CURDATE() + INTERVAL 7 DAY
reference on date_add
I'm assuming that by curdate, you mean the function and not a column name. If it's a column name, change accordingly (although I wouldn't name a column after an existing mySQL function.)
Please try this
select ID, Date from table where Date < DATE_ADD(CURDATE(), INTERVAL 7 DAY)