SQL Server: Understanding DATEDIFF function - sql

I have difficulties understanding the function DATEDIFF. When querying
SELECT DATEDIFF(YEAR, 0, getdate())
I get difference between current year and year 1900 resulting 111. I think that the starttime should be time, not integer like 0. How 0 can be used? Why the start year in 1900, not 1753 as it should be when format is datetime?

It works in datetime because of implicit conversion of 0 to 1st January 1900.
Why not 1900? Why does 0 = 31 Dec 1899 for MS Access? Why are unix timestamps from 01 Jan 1970?
1753 is fairly arbitrary too: it's the major switch to the Gregorian calendar but it isn't consistent. SQL Server 2008 goes back to 01 Jan 0001 with the newer types too.

Related

Unable to convert timestamp to date in Amazon Redshift

I am trying to convert a varchar field into date field using cast(date as date) but it is throwing an error as "Amazon Invalid operation: Error converting text to date".
I tried converting the same column using to_date(date,'Mon DD yyyy') function and it worked fine.
what could be causing this error in cast function and what can I do to rectify it?
I want to use cast specifically for this conversion.
SELECT DISTINCT cast(activity as date)
from akhil_date_conversion;
my activity field has values like:
Nov 24, 2002 9:02 AM
Jan 21, 2002 9:00 AM
Nov 17, 2002 9:00 AM
Nov 5, 2002 9:00 AM
Feb 17, 2002 10:00 AM
Jan 16, 2009 9:03 AM
Apr 20 2002 13:02
May 11 2002 19:34
Aug 11, 2002 12:00 PM
some have AM/PM and some do not!
There is a cluster parameter called datestyle that can be used to set the default date / time format for the cluster. The default is ISO and what you have is closest to POSTGES. This is used in outputting dates but also in interpreting them. However, you don't have a consistent datestyle in your data (12 and 24 hour format changes) so I don't think this will work in your case. You will need to write some SQL get your data into a single format before CAST will work by default.

Updating active record relation time column results in 1 day difference than expected

I'm trying to bulk edit a datetime column on some records, leaving the time alone and only adjusting the date. The below code works unless the time is > 1800. When the record's time is > 1800, the updated date is 1 day less than desired (Wed, 27 Jan 2021 14:25:26 CST -06:00 becomes Wed, 26 Jan 2021 14:25:26 CST -06:00). We're in Central Time (Dallas, TX), so I'd assume it's an issue with timezones, and I think the issue is happening in the process of structuring the new datetime.
I've tried this with DATETIMEFROMPARTS and the 2 options below. Same issue every time.
This is in a Rails 5 app with sql server for the db. target_date is formatted yyyy-mm-dd.
products_relation.update_all("
date_column = DATEADD(
day,
DATEDIFF(dd, date_column, '#{target_date}'),
date_column
)
")
products_relation.update_all("
date_column = CONVERT(
datetime,
CONCAT('#{target_date}', ' ', CONVERT(CHAR(8), date_column, 108))
)
")

Extracting month number and converting it into month name in SQL Server

I came across a SQL query:
select IssuedDate, Convert(char(4), IssuedDate, 0)
from TempTable
and this is its output:
IssuedDate Null
----------------------------------
1964-02-17 00:00:00.0000000 Feb
2018-08-28 00:00:00.0000000 Aug
2018-08-28 00:00:00.0000000 Aug
2018-08-28 00:00:00.0000000 Aug
Can anyone please let me know how the convert function is working and converting month number to month name?
This is using the default format for convert (the third argument is 0), which is "mon dd yyyy hh:miAM". That is, the first three characters in the formatted string are the month abbreviation.
The conversion is to a string with a length of four, it keeps only the first four characters. That would be the month abbreviation and the following character.
In my opinion, a more sensible approach would be:
left(datename(month, issueddate), 3)
This at least works for English, where the month abbreviations are the first the characters of the month name.

SQL Select - Current Date - 7 Year

Hi I am trying to get (current Datetime - Years).
Below is my Query..
print getdate()
print (getdate()-(365.25*7))
Result:
Dec 30 2013 10:47AM
Dec 30 2006 4:52PM
is giving correct result.
But When i try
print getdate()
print (getdate()-year(7))
Result:
Dec 30 2013 10:52AM
Oct 17 2008 10:52AM
Can anyone please tell what is wrong in it?
Rather use DATEADD with the datepart set to YEAR.
Returns a specified date with the specified number interval (signed
integer) added to a specified datepart of that date.
Something like
SELECT GETDATE() Today, DATEADD(YEAR,-7,GETDATE()) Today7YearsAgo
SQL Fiddle DEMO
The year(7) part return 1900, which is the year part of 1900-01-08 00:00:00.000 (CAST(7 AS DATETIME)). Then getdate()-year(7) equates to getdate()-1900, which is a day subtraction.
Try this
print getdate()
print DATEADD(Year, -7, GETDATE())
DATE ADD() Returns a specified date with the specified number interval (signed integer) added to a specified datepart of that date.
print getdate()
print DATEADD(Year, -7, GETDATE())
Try MSSQL DATEADD function
select DATEADD(Year,-7,GETDATE());

Need to identify number that is higher than a given date

I have a date column in a table. The date column is in varchar. I want to identify a particular date range from that date column. My query is like this:
SELECT *
FROM [003 AccptReg].[dbo].[SysData1]
WHERE [RegDate_Sys] > '18 jul 2013'
But the result is not giving accurate result, i.e. it gives dates which are prior of 18 jul 2013.
Is there any thing wrong I am doing?
For date column, you should compare as DATE
select * from [003 AccptReg].[dbo].[SysData1]
where CAST([RegDate_Sys] AS DATE) > CAST('18 jul 2013' AS DATE)
The problem is that you have the date as a varchar, and doesn't convert it to a date when you are doing the comparison. The database doesn't know that you see the data as dates, and will simply compare them as strings, so for example '2 jan 1736' will be larger than '18 jul 2013' because 2 comes after 1.
The best would be if you could store the data as datetime values (or date), then you don't need to do the conversion when you compare the values, which would give better performance.
If that's not possible, do the conversion in the query:
select * from [003 AccptReg].[dbo].[SysData1]
where convert(datetime, [RegDate_Sys], 106) > '18 jul 2013'
Depending on the settings on the server, you might also need to convert '18 jul 2013' in the same way for the database to understand it correctly as a date.
Convert the date to datetime format and then compare:
select * from [003 AccptReg].[dbo].[SysData1]
where convert(datetime,[RegDate_Sys]) >convert(datetime,'18 jul 2013')