EXCEL: When I format the number 43466 as a date I get 1/1/2019
SQL Server: CAST(43466 AS DATETIME) yields Jan 3 2019
Which is correct?
How can I get the correct date in SQL Server?
Related
I need to convert the following SQL server code to PostgreSQL code.
Any help would be appreciated.
SQL Server SQL:
CAST(DATEADD(ww,DATEDIFF(ww,0,trans_date),-1)as date) as week
I think what that code does is to "round" the value of trans_date to the beginning of the week. In Postgres you can do that using the date_trunc() function:
date_trunc('week', trans_date)
Note that this always returns a timestamp, if you need a real date value, cast the result:
date_trunc('week', trans_date)::date
If it should be the day before the beginning of the week, just subtract one day from the result:
date_trunc('week', trans_date)::date - 1
I am working on a replication project where data is replicated on oracle as well as sql server from sybase database.
Basically one of the tables in sybase get populated with the data to be replicated
Sybase column contains data like -
{"a":"b","c":"d","created_date":"'Feb 13 2018 1:33AM'"}
So basically when we are forming query to replicate on sql server and oracle we are using date string 'Feb 13 2018 1:33AM' to convert into date for oracle and sql server.
This date string works fine with the sql server but failed with the error like -
ORA-01858 A NON NUMERIC CHARACTER WAS FOUND WHERE A NUMERIC WAS EXPECTED
So which date format should I use in Sybase so that it will work for both oracle and sql server to replicate.
Oracle will implicitly try to convert strings to dates using the TO_DATE( date_string, format_model, nls_params ) function. Without a format model, Oracle will use the default date format which is a session parameter (so is a per-user setting) stored in the NLS_SESSION_PARAMETERS table and you can find the default value using:
SELECT value
FROM NLS_SESSION_PARAMETERS
WHERE parameter = 'NLS_DATE_FORMAT'
This means the conversion will implicitly be:
TO_DATE(
'Feb 13 2018 1:33AM',
(SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
)
and if the format model does not match your string then you will get an exception.
You can either set the output format to match Oracle's default or you could alter the default date format in the current Oracle session to match your current data using:
ALTER SESSION SET NLS_DATE_FORMAT = 'Mon DD YYYY HH12:MIAM';
You can also create a logon trigger to change the NLS settings when the user connects to the database and starts a session.
The other alternative is that instead of trying to use a string you use a timestamp literal, since you can specify a time component (which you can't with a date literal), and then let Oracle cast it back to a date:
TIMESTAMP '2018-02-13 01:33:00'
or you could explicitly call TO_DATE in your replication query for Oracle and specify the date format:
TO_DATE( 'Feb 13 2018 1:33AM', 'Mon DD YYYY HH12:MIAM' )
I have an issue with my data import from Excel to SQL Server. The datetime value being imported into the destination table is different from the datetime value in the Excel source file.
With or without any formatting the value is always .003 milliseconds less than the actual time in Excel. This causes values that should be marked for 1 AM to be marked for 12 AM when attempting to GROUP BY hour.
Notice my sample query & results to see the exact values.
If someone could tell me why this is happening and how to get my expected results it would be greatly appreciated.
I would also like to resolve this without any additional steps. (No staging tables please)
SELECT
Timestamp,
CAST(Timestamp AS DATE) Date,
CAST(Timestamp AS DATETIME) Datetime,
CAST(Timestamp AS DATETIME2) Datetime2,
CAST(Timestamp AS TIME) Time
FROM
OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel 12.0 Xml;HDR=Yes;
Database=\\server\share\160322.xlsx;',
'SELECT * FROM [160322$]')
/* Query Results (ALL WRONG):
Timestamp : 2016-03-22 00:59:59.997 -- Imported Value without formatting
Date : 2016-03-22 -- Formatted Values
Datetime : 2016-03-22 00:59:59.997
Datetime2 : 2016-03-22 00:59:59.9970000
Time : 00:59:59.9970000
*/
Value in Excel:
3/22/2016 12:15:00 AM
Value in SQL Server table:
2016-03-22 00:14:59.997
Expected SQL Server value:
2016-03-22 00:15:00.000
Value in Excel:
3/22/2016 01:00:00 AM
Value in SQL Server table:
2016-03-22 00:59:59.997
Expected SQL Server value:
2016-03-22 01:00:00.000
The DATETIME datatype in SQL Server has an accuracy of 0.003 seconds - 3.33 milliseconds - that's a well-known and documented fact (see here on MSDN and here a blog post ).
You only get values like .000, .003, .007, .010, .013 etc. - DATETIME does not support values down to the millisecond.
However, using DATETIME2(3) should fix that problem (unless the importing from Excel using OPENROWSET somehow mangles that)
I have a table in SQL Server 2008 R2 with a nvarchar(50) column which stores different formats of date such as 'dd/mm/yyyy', 'mm/dd/yyyy', 'yyyy-mm-dd', etc.
Now I am writing a procedure that will convert/cast this column as a date type. Something as below:
SELECT CONVERT(DATE, Column1) as [Date]
But due to varying formats of date I tend to get the following error in my C# application:
"Conversion failed when converting date and/or time from character string"
I know of a function TRY_CONVERT and TRY_PARSE which can solve this problem but it's only available in SQL Server 2012 and above. Any workaround for this in SQL Server 2008?
I am confused reading statements in "Why is 1899-12-30 the zero date in Access / SQL Server instead of 12/31?"
Was there date type in SQL Server before 2008 version? I cannot find.
In SQL Server 2008 zero date is 0001-01-01. Were there any date type before (in previous SQL Server versions) how is it backward compatible?
No. Prior to SQL Server 2008, there was only the datetime and smalldatetime types.
Data type...............Range..................................................................Accuracy
datetime..................January 1, 1753, through December 31, 9999.....3.33 milliseconds
smalldatetime..........January 1, 1900, through June 6, 2079............... 1 minute
Please see: Date and Time Data in SQL Server 2008, specifically the bit that says "Date/Time Data Types Introduced in SQL Server 2008"
In SQL Server datetime datatype the minimum date that can be stored is 1 Jan 1753.
However the datetimes are stored as numeric offsets to a base date of 1900-01-01 00:00:00.000
SELECT CAST(-0.25 AS DATETIME) /*1899-12-31 18:00:00.000*/
SELECT CAST(0 AS DATETIME) /*1900-01-01 00:00:00.000*/
SELECT CAST(0.25 AS DATETIME) /*1900-01-01 06:00:00.000*/
1899-12-30 has no significance in SQL Server.
SELECT CAST(CAST('1899-12-30' AS DATETIME) AS FLOAT) /*Returns -2*/