SQL date format picture ends before converting entire input string - sql

I am trying to execute a query looking something like this:
create table A as
select
userid, to_date(date1, 'mm/dd/yyyy') as startDate,
to_date(date2, 'mm/dd/yyyy') as endDate
from TABLE;
I am getting the error:
ORA-01830: date format picture ends before converting entire input string
What's really strange here is that when I run only the SELECT... part of the query it works perfectly, I am only getting the error when I try to create a table. I absolutely need to make a table, so how can I get around this?
Thanks!

There's likely some bad data past the first few rows. When you run the select, it will do the conversion for the first few (less than 1000 for me) rows only. The results are paged. You'll need to clean up the data first. You could write a simple function like this to figure out which dates it's failing on.
How to handle to_date exceptions in a SELECT statment to ignore those rows?

Related

Extract date from timestamp containing time zone in Big Query

I have data containing dates of the form
2020-12-14T18:58:10+01:00[Europe/Stockholm]
but I really only need the date 2020-12-14.
So, I tried:
DATE(Timestamp) as LastUpdateDate
which returned Error: Invalid time zone: +02:00[Europe/Stockholm]
So, thinking that the problem came from the time zone, I tried this instead:
TIMESTAMP(FORMAT_TIMESTAMP("%Y-%m-%d", PARSE_TIMESTAMP("%Y%m%d", Timestamp)))
which magically returned a new error, namely
Error: Failed to parse input string "2021-10-04T09:24:20+02:00[Europe/Stockholm]"
How do I solve this?
Just substring the date part from the string. Try one of these:
select left(Timestamp, 10)
select date(left(Timestamp, 10))
You should clean your data first.
select date("2020-12-14T18:58:10+01:00") as LastUpdateDate
This will work as expected.
Any chance of cleaning your data before using it in a query? Actually I think that +01:00[Europe/Stockholm] is not supported as format.

Trying to query data based on range of date but for only one time point

I am trying to query a MSSQL database through SQuirreL, which works if I just want all data through a range of timestamps. However, I would like to query a range of dates but for only one time point. I have been successful at performing this type of query in postgresql, but I am not as familiar with MSSQL sql queries.
SELECT * FROM table WHERE timestamp >='06/04/19 00:00:00' AND
(TimeValue(timestamp) BETWEEN '23:40:00' AND '23:55:00');
I can use the line of code to work if I select just a date or timestamp range, but once I add the time value I get no matching data even though I know it is there.
I am sure that I am just not doing the syntax correct, or for MSSQL there is different way to do this. Thank you.
What query did you generate, when you didn’t receive data? I assume you did a mistake with “and/or”. The query you are looking for probably looks like the following:
`WHERE (TIME(timestamp) BETWEEN {t ‘12:00:00’} AND {‘t 14:00:00’}) AND ((DATE(timestamp) BETWEEN var1 AND var2) AND (DATE(timestamp) BETWEEN var1 AND var2))`

ORACLE SQL Trim ineffective with Regular Expressions

CLARIFICATION
When I simplify the query, i.e.
SELECT TO_CHAR(MIN(I.INCIDENTID)) AS "Incident ID",
TRIM(TO_CHAR(I.CREATIONDATE,'DD-MON-YYYY')) AS "Creation Date"
FROM INCIDENT I
GROUP BY TRIM(TO_CHAR(I.CREATIONDATE,'DD-MON-YYYY'))
I get
But if I incorporate into my actual query for 164,000+ distinct rows, I get
But I expect this (only difference is, Creation Date must have proper Date format, not this complex string)
ORIGINAL QUESTION
I am reading a date-time from an external Oracle Database, and have trimmed any extra spaces successfully with TRIM(I.CREATIONDATE).
I have verified this because my SQL query only displays distinct date values
However, TRIM(I.CREATIONDATE) turns 2/26/2019 11:05:44 AM into 26-FEB-19 11.05.43.925000 AM, but I only want 26-FEB-19
When I apply regular expression to only get date, i.e. REGEXP_SUBSTR(TRIM(I.CREATIONDATE),'[^ ]+'), it certainly outputs 26-FEB-19, but somehow extra spaces are added because I get duplicate dates.
I have tried applying TRIM a second time, i.e. TRIM(REGEXP_SUBSTR(TRIM(I.CREATIONDATE),'[^ ]+')), but I still get duplicates
Then I tried running regular expression first, then trim, but this does not work, i.e. TRIM(REGEXP_SUBSTR(I.CREATIONDATE,'[^ ]+')) still gives duplicates.
Please assist
I think you want trunc(), not trim() to remove the time component.
So try:
trunc(i.creationdate)
Or if you want the days in a particular string representation:
to_char(i.creationdate, 'YYYY-MM-DD')
Try to_char:
trim(to_char(column_name,'dd-mon-yy'))

Comparing dates in SQL returns wrong records

I am trying to locate a date in database between two specific dates entered by user. Something like:
SELECT date FROM table WHERE date>=dateFrom AND date<=dateTO
I have the following table:
I have made a mistake saving the date as VARCHAR and now i have to do all the str_to_date and date_format as i am using phpMyAdmin. I somehow did it but i am facing this strange problem using this query:
SELECT date_format(str_to_date(data,'%d/%m/%Y'),'%d/%m/%Y') AS data FROM montaggio WHERE data>=date_format(str_to_date('29/08/2014','%d/%m/%Y'),'%d/%m/%Y')
The query would return to me only the date 19/08/2014 where as i expected it to return 01/09/2014. On the other hand if it enter the query
SELECT date_format(str_to_date(data,'%d/%m/%Y'),'%d/%m/%Y') AS data FROM montaggio WHERE data>=date_format(str_to_date('29/08/2014','%d/%m/%Y'),'%d/%m/%Y') AND data<=date_format(str_to_date('05/09/2014','%d/%m/%Y'),'%d/%m/%Y')
The query returns nothing.
I am using phpMyAdmin.
What am i missing here? Any help would be appreciated!
You do seem a bit confused. All the operations on dates should be done on the date data type. There is no need to convert things back to strings:
SELECT data
FROM montaggio
WHERE str_to_date(data, '%d/%m/%Y') >= str_to_date('29/08/2014', '%d/%m/%Y')
You seem to understand the real solution, which is to store dates/times in the database using the correct type. If you have to use strings for dates, then always stored them as YYYY-MM-DD, so comparisons and sorting will work correctly.

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?