SQL Server 2012 - Convert CYYMMDD date to YYYYMMDD - sql

I have a table with just over 200,000 entries where the date is stored as CYYMMDD where C is the century (currently stored as integers). For example, December 5, 1992 would show up as 1921205 and April 25, 2016 would show up as 2160425. I need to display these results in a new table in a YYYMMDD format. So for the two examples earlier it would be 19921205 and 20160425. I have tried using
CONVERT(VARCHAR(8),[DATE], 112)
This doesn't give an error but it also doesn't do the conversion so all my dates still look the same. What am I doing wrong?

You'll need to split your numeric value as follows:
DATEFROMPARTS( 1800 + FLOOR([DATE]/10000) , FLOOR([DATE]/100)%100, [DATE]%100 )

Related

LEFT Function in SQL Server returns no results

I am trying to place data corresponding to a certain month into a temp table from an SQL database.
DROP TABLE
#ComPAIR_Alliance_Table
SELECT
IMOno
,period
,[service]
,alliances
INTO
#ComPAIR_Alliance_Table
FROM
com_COMPAIR.dbo.Data_BlueWaterCapacity_US_2
WHERE
LEFT(period, 7) = '2015-03'
SELECT
*
FROM #ComPAIR_Alliance_Table
The period field is in the following format: 2015-03-29 00:00:00.000
However, my code just returns an empty temp table with the right column names but no rows (even though I know for sure rows with that date exist in my table). I have already made sure that the period column is indeed a string by using is.numeric.
Could someone please help me out with what the problem could be?
Thanks!
If it is a date/datetime/datetime2 then you can compare it with 2015-03 like:
WHERE period >= '2015-03-01'
AND preiod < DATEADD(MONTH, 1, '2015-03-01')
In case there is confusion:
The above will match all March 2015 dates such as 2015-03-31, 2015-03-31 23:59:59 and 2015-03-31 23:59:59.9999999
The above is sargable: the DATEADD part does not depend on the table rows
Guessing Period is a date. If it is, stop treating it like a varchar, it isn't one. If you want values from March 2015 then do:
WHERE period >= '20150301'
AND period < '20150401'
LEFT is doing some weird stuff, because LEFT causes an implicit cast to String from Date. You can see this question for more information, but you're getting exactly what you told SQL to get - a join on rows where the left 7 characters of period equal '2015-03' which will not happen, since you're liking comparing against something like 'Jan 01'
The LEFT function needs to implicitly convert your datetime column to a varchar value to do it's work. SQL Server is choosing the varchar format of the date based on it's internationalization settings. On my server, its Mar 29 2015 12:00AM, and LEFT yields Mar 29. That's why it's not equal to 2015-03.
You should treat your column as a datetime and then perform the comparison using a valid datetime comparison, like this :
WHERE period BETWEEN '1/1/2015' AND '1/31/2015'
the date is stored as a date type. You may want to try
where convert(varchar(20), period,121)
which would convert it to string...

AS400 Emulator cant process dates less than 1940 or greater than 2039

I have this simple SQL script:
SELECT DATE(SUBSTR( '19310205' , 1 , 4)
|| '-' || SUBSTR ('19310205' , 5 , 2)
|| '-' || SUBSTR('19310205', 7 , 2))
FROM MY_TABLE;
Whenever I run the script on the iSeries navigator, I get the expected output which is
1931-02-05
However, when I run it on the AS400 Emulator using the strsql command, I get the following output:
++++++++
I have no idea why this happens; all I know is that only the dates between 1940-2039 are working well. Can anyone explain why?
Also, is there a way for the other dates be processed successfully as well?
In your AS/400 emulator session, press "F13=Services".
Select "1. Change Session Attributes"
Change the "Date Format" to "*ISO" or desired format supporting a full date range.
From the IBM Knowledge Center, "Rational Developer for i7.1.0":
A date is a three-part value (year, month, and day) designating a point in time >under the Gregorian calendar20, which is assumed to have been in effect from >the year 1 A.D. The range of the year part is 0001 to 9999. The date formats >*JUL, *MDY, *DMY, and *YMD can only represent dates in the range 1940 through >2039. The range of the month part is 1 to 12. The range of the day part is 1 to >x, where x is 28, 29, 30, or 31, depending on the month and year.
I just want to build on Richard Evans answer, but since there is too much to put into a comment, I will make it a new answer.
IBM i has a native date type that can store dates from January 1, 0001 to December 31, 9999. The date type has a format which specifies, among other things, the number of digits in the year portion of the date. There are two main groupings that affect the range of dates that can be accepted. Two digit year formats which can accept dates from January 1, 1940 - December 31, 2039. These are: *MDY, *DMY, *YMD, and *JUL. Four digit year formats can handle the full range of dates that the date type supports. These are *ISO, *USA, *EUR, *JIS.
In addition to the main formats which are supported everywhere date formats are supported, RPG supports a few other date formats: *JOBRUN, three digit year formats, and *LONGJUL. *JOBRUN is a two digit year format, and can only be specified for numeric and character date fields with 2 digit years. This uses the job date format and seperator values. Three digit year formats can handle dates from January 1, 1900 - December 31, 2899. These are *CMDY, *CDMY, and *CYMD. The C in the three digit year formats represents the two most significant digits of the year portion of the date where:
0 => 1900 - 1999
1 => 2000 - 2099
2 => 2100 - 2199
...
9 => 2800 - 2899
Finally *LONGJUL is a four digit year Julian format.
Internally dates are stored in an *ISO format. The other formats are external formats. In fact when defining tables with SQL you don't even get to specify the date format, it just defaults to *ISO. In places that you can specify the format, it is just an external format that you are specifying. It is best to use *ISO for all working fields and database files, even when using DDS. Then reserve other external formats like *MDY or *DMY for user facing fields to convert the *ISO format into a more localized format. This way you can store the full range of dates that users can input or view.
Return a character representation of a date in any format using the varchar_format() function. Regardless of session defaults or where its run from.
SELECT
cast(
varchar_format(
cast(
DATE(SUBSTR( '19310205' , 1 , 4)
|| '-' || SUBSTR ('19310205', 5 , 2)
|| '-' || SUBSTR('19310205', 7 ,2))
as timestamp )
, 'YYYY-MM-DD')
as char(10)) as mydate
FROM sysibm/sysdummy1
MYDATE
1931-02-05
******** End of data ********

SQL Server DATEPART() function

Today I wrote two queries on Datepart() and get different returns below
Query #1:
Select Datepart(day,'2015-07-05')
returns '5', which I expected.
Query #2:
Select Datepart(day, 2015-07-05)
Returns '27', which is a little bit funny, and I don't understand how 27 is being returned.
The difference between these two queries is one with the date inside ' ', and the other without.
Anybody can help me out here?
2015-07-05 is just a mathematical expression which adds up to the integer 2003. (Subtracting 7 from 2015 gives 2008 then subtract 5)
2003 evaluates to '1905-06-27' when implicitly cast to datetime as casting int to datetime works the same as adding that number of days to the base date of 1 Jan 1900 (i.e. equals DATEADD(DAY, 2003,'19000101')).
So this is where the 27 comes from.
The correct way to denote date literals in SQL Server is as a string '2015-07-05' (ISO format - unambiguous for newer datetime datetypes) or '20150705' (unambiguous for legacy datatypes) or using the ODBC format { d '2015-07-05' }.

Select most recent records by DB2 date in form of YYYYMMDD

I am importing records from a DB2 data source into a MS SQL Server destination.
The records are coming in with the date format of 20150302/YYYYMMDD, but I only want the last 14 days based on current server date.
Can some advise on how to select based on this date format against DATEADD(d, - 1, { fn CURDATE() }) please.
Thanks!
It would be better to do this on the DB2 side, to reduce the number of records brought over.
Additionally, it's better from a performance standpoint to convert the static date into a numeric date and compare to the column in your table. Rather than convert the numeric date in your table to a actual date type for comparison.
where numdate >= int(replace(char(current_date - 14 days,iso),'-',''))
Doing it this way will allow you to take advantage of an index over numdate. In addition, DB2 will only need to perform this conversion once.
Depending on your platform & version, you may have an easier way to convert from a date data type to a numeric date. But the above works on DB2 for i and should work on most (all?) DB2 versions and platforms.
You may find it worthwhile to create a UDF to do this conversion for you.
If you want logic in SQL Server, then you are in luck, because you can just convert the YYYYMMDD format to a date:
where cast(datecol as date) >= cast(getdate() - 14 as date)
(This assumes no future dates.)
If you want to do this on the DB2 side, you can use to_date():
where to_date(datecol, 'YYYYMMDD') >= current date - 14 days

SELECT CONVERT(VARCHAR(10), GETDATE(), 110) what is the meaning of 110 here?

When we convert or cast date in sql, see below sql code
SELECT CONVERT(VARCHAR(10), GETDATE(), 110) AS [MM-DD-YYYY]
it works fine, I just want to know the meaning of 110 in above code. what it does actually, sometimes we use 102, 112 etc. what is the use of that number.
That number indicates Date and Time Styles
You need to look at CAST and CONVERT (Transact-SQL). Here you can find the meaning of all these Date and Time Styles.
Styles with century (e.g. 100, 101 etc) means year will come in yyyy format. While styles without century (e.g. 1,7,10) means year will come in yy format.
You can also refer to SQL Server Date Formats. Here you can find all date formats with examples.
110 is the Style value for the date format.
TSQL Date and Time Styles
When you convert expressions from one type to another, in many cases there will be a need within a stored procedure or other routine to convert data from a datetime type to a varchar type. The Convert function is used for such things. The CONVERT() function can be used to display date/time data in various formats.
Syntax
CONVERT(data_type(length), expression, style)
Style - style values for datetime or smalldatetime conversion to character data. Add 100 to a style value to get a four-place year that includes the century (yyyy).
Example 1
take a style value 108 which defines the following format:
hh:mm:ss
Now use the above style in the following query:
select convert(varchar(20),GETDATE(),108)
Example 2
we use the style value 107 which defines the following format:
Mon dd, yy
Now use that style in the following query:
select convert(varchar(20),GETDATE(),107)
Similarly
style-106 for Day,Month,Year (26 Sep 2013)
style-6 for Day, Month, Year (26 Sep 13)
style-113 for Day,Month,Year, Timestamp (26 Sep 2013 14:11:53:300)
10 = mm-dd-yy
110 = mm-dd-yyyy
SQL Server CONVERT() Function