Function to convert char(255) non standard dates into timestamps - sql

I have database with a column of date strings that are in the format YYYY-MM-DDThh:mm:ss.3nZ
I would like to transform them into TIMESTAMP so that I can then apply the BETWEEN function to identify rows that fall in a given time window (this being the ultimate goal of the exercise).
I can't just change the nature of the column unfortunately.
What is the best way to achieve this?
Thank you

Try this:
SELECT
to_timestamp('2021-01-28T10:26:32.359Z', 'YYYY-MM-DD"T"HH:MI:SS.FF3"Z"') t
FROM
dual;

Related

How to check TIMESTAMP format in SQL?

What's the best way to check if the VARIANT TYPE with JSONs with value similar to TIMESTAMP_NTZ has correct format?
For example, this is the correct format that I would like to have
2020-12-26T12:12:11.215581Z
but there are times when it looks different in database, like this
2021-11-26T12:12:11.215581Z[UTC]
I would like to detect records which are in a different format than the reference.
I tried with simple LIKE, but it omits formats that could be different than this.
LIKE '%[UTC]%'
You may use a regular expression to check the equality of the desired format. I will extend this answer if the rdbms is known.
[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{6}Z
MySQL & SQLite:
SELECT * FROM table
WHERE timestamp not REGEXP '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{6}Z';
Oracle:
SELECT * FROM table
WHERE not REGEXP_LIKE(timestamp, '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{6}Z');
If all the records you want to detect come in addition to the end of the format that should be then you can use length.
Basically:
WHERE NOT len(column_name)=27
27 because your correct format 2020-12-26T12:12:11.215581Z has 27 characters.

How to convert an integer field into a date in Netezza?

i have an integer field which has date values but i would like to convert it as date field. I have tried several methods but with no success. The field has Date values but is stored as an Integer. This is what i have tried:
cast(MYFIELD AS DATE) AS MYCOLUMN
but i get this error "Cannot cast type INT4 to DATE".
I have done several research but coul not find good solution for netezza.
You can concatenate 01 and then run a to_date
select to_date(201004||'01','YYYYMMDD')
I don't think this is something that you can do, not in an obvious way at least. There are hundreds of ways a human could represent a date as an int, so the conversion would not be built in.an int would be something like 20120415 or 04152013 or hundreds of other formats and a date would be something like '2012-04-15'
I suggest you look at the top answer for How i can get the first 3 digits in 123456 Numbers in sql? and extract your data manually. what you should do though, is convert the field into a real date field and edit the dependencies to expect that format.

Insert only Month and Year date to SQL table

I am using MS SQLServer and trying to insert a month/year combination to a table like this:
INSERT INTO MyTable VALUES (1111, 'item_name', '9/1998')
apparently, the above command cannot work since
Conversion failed when converting date and/or time from character string.
Because 9/1998 is a bad format. I want to fix this and this column of the table will show something like:
9/1998
12/1998
(other records with month/year format)
...
Can someone help me with this?
thank you
SQL Server only supports full dates (day, month, and year) or datetimes, as you can see over on the MSDN data type list: http://msdn.microsoft.com/en-us/library/ff848733(v=sql.105).aspx
You can use a date value with a bogus day or store the value as a string, but there's no native type that just stores month/year pairs.
I see this is an old post but my recent tests confirm that storing Date or splitting the year and month to two columns (year smallint, month tinyint) results in the overall same size.
The difference will be visible when you actually need to parse the date to the filter you need (year/month).
Let me know what do you think of this solution! :)
Kind regards
You can just use "01" for the day:
INSERT INTO MyTable VALUES (1111, 'item_name', '19980901')
You can:
1) Change the column type to varchar
2) Take the supplied value and convert it to a proper format that sql server will accept before inserting, and format it back to 'M/YYYY' format when you pull the data: SELECT MONTH([myDate]) + '/' + YEAR([myDate]) ...
You may want to consider what use you will have for your data. At the moment, you're only concerned with capturing and displaying the data. However, going forward, you may need to perform date calculations on it (ie, compare the difference between two records). Because of this and also since you're about two-thirds of the way there, you might as well convert this field to a Date type. Your presentation layer can then be delegated with the task of displaying it appropriately as "MM/yyyy", a function which is available to just about any programming language or reporting platform you may be using.
if you want use date type, you should format value:
declare #a date
SELECT #a='2000-01-01'
select RIGHT( convert (varchar , #a, 103), 7) AS 'mm/yyyy'
if you want make query like SELECT * FROM...
you should use varchar instead date type.

How to update dates stored as varying character formats (PL/SQL)?

Problem: I have a large database table (~500k records) which has a list of dates stored in a varchar2(15) column. These dates are stored in varying formats, ie. some are yyyy-mm-dd, some are mm/dd/yyyy, some are dd/mm/yy, some are mm/dd/yy, etc. Ie:
1994-01-13
01/13/1994
01/13/94
13/01/94
13/01/1994
etc
I need to be able to shift these dates slightly, for example to add 30 days to each date. (This is an oversimplification of my objective but it's easier to explain this way).
If all the dates were formatted consistently, I would achieve this as follows:
UPDATE history_table
SET some_date_col =
to_char(to_date(some_date_col, 'mm/dd/yyyy')+30, 'mm/dd/yyyy')
WHERE some_date_col IS NOT NULL;
Due to the size of the database, I cannot afford to loop through the values one by one and parse the date value. Can anyone suggest a means to accomplish this without loops, ie with a mass UPDATE statement?
Are the formats of these dates really that important? They should be datetime columns. Then you could just use date math functions on that field.
well, you've got a real problem here.
07/07/1994 is valid for 'MM/DD/YYYY' and 'DD/MM/YYYY'
However, outside of that issue, you can try nesting decodes.
I entered the following dates into a varchar field:
01/12/2009, 01-12-2009, 2009-01-12, 01/12/09
and using the below, I was consistently returned 1/12/2009. You'll have to figure out all the patterns possible and keep nesting decodes. The other thing you could do is create a function to handle this. Within the function, you can check with a little more detail as to the format of the date. It will also be easier to read. You can use the function in your update statement so that should be faster than looping through, as you mentioned.
(for what its worth, looping through 500k rows like this shouldn't take very long. I regularly have to update row by row tables of 12 million records)
select mydate,
decode(instr(mydate,'-'),5,to_date(mydate,'YYYY-MM-DD'),3,to_date(mydate,'MM-DD-YYYY'),
decode (length(mydate),8,to_date(mydate,'MM/DD/YY'),10,to_date(mydate,'MM/DD/YYYY')))
from mydates;
and here is the update statement:
update mydates set revdate = decode(instr(mydate,'-'),5,to_date(mydate,'YYYY-MM-DD'),3,to_date(mydate,'MM-DD-YYYY'),
decode (length(mydate),8,to_date(mydate,'MM/DD/YY'),10,to_date(mydate,'MM/DD/YYYY')))
IMHO, you have a bigger problem:
If some dates are dd/mm/yyyy and some are mm/dd/yyyy how can you difference which format applies for certain date?
for example, how can I know if a value "12/09/2008" means December or September?

MS Access - Select Char as Date and doing a date diff

I have two columns. ColA and ColB contains char(10) with data "20090520" and "20090521".
I want to select and get the date difference in days. I have tried using Format() and CDate()
but MS Access always display as #ERROR.
Access prefers its dates in this format:
#2009-12-01#
You can convert your date to something Access understands with:
CDate(Format([ColA], "0000-00-00"))
Or alternatively:
DateSerial(Left([ColA],4),Mid([ColA],5,2),Right([ColA],2))
And to display the result in your preferred format:
Format(<date here>, "dd-mm-yyyy")
Try using DateSerial() to convert the dates:
DateSerial(Left([FieldName],4),Mid([FieldName],5,2),Right([FieldName],2))
If at all possible, change the datatype to a date datatype. You should not store dates as character data.
I am connecting to another database which I have no control on. That is why this problem occurred. Thanks for the feedback.