How to add a date in SQL? - sql

How to add or sub a date?
SELECT DATEADD(month, -1, '2017-08-25') AS DATEADD
ERROR:
Msg 242, Level 16, State 3, Line 98
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

Your query works fine in SQL Server (see here).
You may have arcane internationalization settings that do not treat '2015-08-25' as YYYY-MM-DD.
There are two choices. You can drop the hyphens:
SELECT DATEADD(month, -1, '20170825') AS DATEADD
SQL Server always treats date strings with eight digits as a date in the format YYYYMMDD.
Or do an explicit conversion:
SELECT DATEADD(month, -1, CONVERT(DATE, '2017-08-25', 120)) AS DATEADD

1- If you have date datatype of your column then you can directly do add or sub on date like below
select datecol -1 as sub_op , datecol+1 as sub_op2 from your_table
2- If you want to convert string to date in oracle you can use to_date function as below
select to_date('28-May-2019','DD-MM-YYYY') from dual;
or if mysql
STR_TO_DATE('2013-02-11', '%Y-%m-%d')

enter code here
SELECT convert (varchar(15),DATEADD(day, 1, '2017/08/25'),103) AS DateAdd; -- dd/MM/YYYY only
SELECT convert (varchar(15),DATEADD(DAY, -1, '2017/08/25'),103) AS DateAdd; -- dd/MM/YYYY
1.year, yyyy, yy = Year
2.quarter, qq, q = Quarter
3.month, mm, m = month
4.dayofyear = Day of the year
5.day, dy, y = Day
6.week, ww, wk = Week
7.weekday, dw, w = Weekday
8.hour, hh = hour
9.minute, mi, n = Minute
10.second, ss, s = Second
11.millisecond, ms = Millisecond

Related

SQL Server / How to sort a duration from two datetime?

I was wondering if it's possible to sort a duration from two datetime. For example, I want the duration between '2019-12-09 09:00:00' and '2019-12-09 15:00:00'.
A simple subtraction could work?
The unambiguous way to write this is (i.e. increase the 2nd date by 1 and make it <)
select *
from xxx
where dates >= '20191026'
and dates < '20191028'
If you're using SQL Server 2008 or above, you can safety CAST as DATE while retaining SARGability, e.g.
select *
from xxx
where CAST(dates as DATE) between '20191026' and '20191027'
This explicitly tells SQL Server that you are only interested in the DATE portion of the dates column for comparison against the BETWEEN range.
You can use DATEDIFF fro your purpose. based on your requirement, you can define the duration for
year, yyyy, yy = Year
quarter, qq, q = Quarter
month, mm, m = month
dayofyear = Day of the year
day, dd, y = Day
week, ww, wk = Week
weekday, dw, w = Weekday
hour, hh = hour
minute, mi, n = Minute
second, ss, s = Second
millisecond, ms = Millisecond
Script-
WITH your_table(st_date,end_date)
AS
(
SELECT '20190102', '20190103' UNION ALL
SELECT '20190102', '20190105'
)
SELECT st_date,end_date,
DATEDIFF(DD,st_date,end_date)
FROM your_table
ORDER BY DATEDIFF(DD,st_date,end_date) DESC
DEMO HERE
Output will give duration output in Hr:Min format
SELECT CONCAT(datediff(HH,'2019-12-09 09:00:00','2019-12-09 15:00:00'),':', DATEDIFF(Minute,'2019-12-09 09:00:00','2019-12-09 15:30:00')%60)
Use DATEDIFF
DECLARE #StartDate datetime, #EndDate datetime
SELECT #StartDate = '2019-12-09 09:00:00' ,#EndDate='2019-12-09 15:00:00'
SELECT convert(varchar(5),DateDiff(s, #startDate, #EndDate)/3600)+':'+convert(varchar(5),DateDiff(s, #startDate, #EndDate)%3600/60)+':'+convert(varchar(5),(DateDiff(s, #startDate, #EndDate)%60)) as [hh:mm:ss]
Output looks like
hh:mm:ss
6:0:0
If you are using sqlserver you can use this function:
-- as minute
select datediff(minute,'2019-12-09 09:00:00','2019-12-09 15:00:00')
-- as hour
select datediff(hour,'2019-12-09 09:00:00','2019-12-09 15:00:00')

Convert date (yyyy-mm-dd) to MM-YYYY in SQL

I would like to convert a date in yyyy-mm-dd (Date format, length 10) to mm-yy format.
I have so far tried "right", "Left" and "convert" functions to no avail.
What's the exact syntax I need to use?
SELECT
LEFT (day,7) as 'YYYYMM'
FROM bi_core.fact_campaign_device_stats_daily
WHERE DAY = '2019-07-01'
SQL Error [3457] [42883]: [Vertica][VJDBC](3457) ERROR: Function LEFT(date, int) does not exist, or permission is denied for LEFT(date, int)
In Vertical, use to_char():
SELECT to_char(day, 'MMYY') as mmyy
FROM bi_core.fact_campaign_device_stats_daily
WHERE DAY = '2019-07-01'
For SQL database:
SELECT FORMAT(day, 'MM-yyyy') AS 'new_format'
FROM bi_core.fact_campaign_device_stats_daily
WHERE DAY = '2019-07-01'
Or also, to get it numeric:
SELECT YEAR("day") * 100 + MONTH("day") AS yearmonth
FROM bi_core.fact_campaign_device_stats_daily
WHERE "day" = '2019-07-01'

get the first n characters of getdate()

I have a case compare date, hour of datetime column and current date,hour
select * from tbl where LEFT(EVENT_TIME_column,13) !=LEFT(GETDATE(),13)
EVENT_TIME_column format is '2019-08-15 12:32:40.0000000'
when i perform LEFT(GETDATE(),13) result is 'Aug 15 2019'
can you suggest how to get GETDate() in '2019-08-15 12' (date and hour)
If you want the format yyyy-MM-dd hh then can do this:
SELECT CONVERT(varchar(13),GETDATE(),120);
db<>fiddle
You can find a full list of all the style codes for CONVERT in the documentation: Date and Time Styles
However, it looks like you want to check if the date is within the current hour. That would be:
WHERE EVENT_TIME_column >= DATEADD(HOUR, DATEDIFF(HOUR, 0,GETDATE()),0)
AND EVENT_TIME_column < DATEADD(HOUR, DATEDIFF(HOUR, 0,GETDATE())+1, 0)
This explicitly avoids any functions on the column EVENT_TIME_column; which would make the query non-SARGable.
Don't use string functions on date/time values! There are perfectly good built-in functions:
where convert(date, event_time_column) = convert(date, getdate()) and
datepart(hour, event_time_column) = datepart(hour, getdate())
If you don't care about index usage, then use datediff():
where datediff(hour, event_time_column, getdate()) = 0
You can check this with 2 separate comparison as below. This is for checking Date and Hour part is same as date and hour part if GETDATE() or not.
WHERE CAST(EVENT_TIME_column AS DATE) = CAST(GETDATE() AS DATE)
AND DATEPART(HH,EVENT_TIME_column) = DATEPART(HH,GETDATE())
To check NOT EQUAL TO, Just replace = sign with != sign.
In addition, If I guess correct you are only trying to avoid records from running hour of to date. If this is the case, you can also filter your data with below logic-
WHERE EVENT_TIME_column < DATEADD(hh, DATEDIFF(hh, 0, getdate()), 0)

MMYYYY compare to YYYYMMDD

i have dates stored as chars in db (i know, but its not my db nor my idea..).
One of the dates is stored as MMYYYY (012016,022016...) and the second one is stored as YYYYMMDD (20160101,20160202...).
Is there a way to compare those dates? I need to take one date and select all of the second dates which are at least one year older then the first one...
Thank you for any help !
So for example i have Date1 field with values : 012014,012015,012016
and Date2 field with value: 20141005
And i need only Date1 which is at least one year older then Date2 so in this case it will return only 012016
I make two ctes to show how to work it out. I assume MMYYYY are stored as nvarchar or varchar and YYYYMMDD are the same type. If not - you will need one/few conversions on YYYYMMDD field.
;WITH cte AS (
SELECT '012016' as MMYYYY
UNION ALL
SELECT '022016'
), cte2 AS (
SELECT '20160101' AS YYYYMMDD
UNION ALL
SELECT '20160202'
)
SELECT *
FROM cte c
INNER JOIN cte2 c2
ON YYYYMMDD LIKE RIGHT(MMYYYY,4)+LEFT(MMYYYY,2) +'%'
Output:
MMYYYY YYYYMMDD
012016 20160101
022016 20160202
EDIT:
To find out differences in years use this:
DATEDIFF(year,CAST(YYYYMMDD as date), CAST(RIGHT(MMYYYY,4)+LEFT(MMYYYY,2)+'01' as date))
You can convert both fields into type DATE, then compare them.
For MMYYYY, you can use the function DATEFROMPARTS() to build a date. For example, convert 012014 into date:
-- DATEFROMPARTS(year, month, day)
DATEFROMPARTS(RIGHT('012014', 4), LEFT('012014', 2), 1)
For YYYYMMDD, it is easier, because this is the format ISO with Time Style 112. You can use the CONVERT() function to do the conversion :
CONVERT(DATE, '20141005', 112)
And here's how the final query looks like :
WITH casted AS (
SELECT
DATEFROMPARTS(RIGHT(date1, 4), LEFT(date1, 2), 1) AS d1,
CONVERT(DATE, date2, 112) AS d2,
-- ...
FROM yourTable
)
SELECT *
FROM casted
WHERE d1 <= DATEADD(YEAR, -1, d2)
try this
column1 is stored MMYYYY format and column2 is stored YYYYMMDD.
where column1= case when datepart(month,taskDuedate)>9 then convert(varchar,datepart(month,taskDuedate))else '0'+convert(varchar,datepart(month,taskDuedate))end+convert(varchar,datepart(year,taskDueDate))

SQL date selecting

I want to be able to select all database rows where the month and year are the same as what I am searching for. Since the DATE field has year, month, and day, how do I search with year and month?
SELECT *
FROM tblTableName
WHERE Month(ColumnDate) = Month(MyDate)
AND Year(ColumnDate) = Year(MyDate)
SELECT *
FROM myTable
WHERE ( YEAR(myfield) = '2009')
AND ( MONTH(myfield) = '1')
The most efficient is to create the start and end date of the range that you want, so that you compare the dates as a single value instead of extracting the year and month properties from each date.
Example:
select SomeField
from SomeTable
where SomeDate >= ? and SomeDate < ?
(Note that the first comparison is inclusive and the seond is exclusive.)
Create the start and end date to use as parameters: (example in C#)
DateTime start = new DateTime(date.Year, date.Month, 1)
DateTIme end = start.AddMonths(1);
In MySQL:
SELECT *
FROM mytable
WHERE date >= STR_TO_DATE(CONCAT(EXTRACT(YEAR_MONTH FROM #mydate), '01'), '%Y%m%d')
AND date < STR_TO_DATE(CONCAT(EXTRACT(YEAR_MONTH FROM #mydate), '01'), '%Y%m%d') + INTERVAL 1 MONTH
This will efficiently use an index on the date field.
That would depend on what database backend you are using. IN SQl Server I would use
where year(datefield) = #year and month (datefield) - #month
to do this.
or you could build a where clause by creating a date range
where datefield between 20090101 and 20090201
You will want to use MONTH() and YEAR() in mysql.