Bad date format Oracle SQL - sql

I'm facing an issue with date format. I need the row with the max(date1)
I don't think that my query is incorrect :
SELECT column1,
column2,
date1
FROM table
WHERE date1 = (SELECT MAX(date1) FROM table);
When i use this query in dev environment with TOAD, i'm receiving that result :
column1;column2;date1
aaaaa;bbbbb;19/09/2014 14:13:21
But, when i ask our infrastructure to make this query in production, they returned me that result :
column1;column2;date1
ccccc;dddddd;14/09/26
The date isn't in good format... What can i do the receive the good date ? Does i have to specified the format in my query ? Or does the infra team messed up somethings while giving me the result ?
Thanks in advance for your help

date1 is a date column - it doesn't have any intrinsic format - that's up to the client and the environment to determine when printing it.
If you want to control the format, you need to do so explicitly with the to_char function:
SELECT column1,
column2,
TO_CHAR(date1, 'DD/MM/YYYY hh24:mi:ss')
FROM table
WHERE date1 = (SELECT MAX(date1) FROM table);

Related

Big Query Multiple Date Format

I have a table that have multiple date format on big query table. The Date format is followed:
(please note, this is coming from staging table so the data type is defaulted as string type.
mm/dd/yyyy
yyyy-mm-dd
I'm trying to standardized date format to yyyy-mm-dd. Here is the query as followed:
select calendar_date,
FORMAT_DATE('%Y-%m-%d',safe_cast(calendar_date as date))
FROM `calendar_dates.table`
The result that came out as null
please let me know if there is another way to solve this.
Use below
SELECT
calendar_date,
COALESCE(SAFE.PARSE_DATE('%Y-%m-%d', calendar_date), SAFE.PARSE_DATE('%d/%m/%Y', calendar_date))
FROM `calendar_dates.table`
The below query, that uses safe.parse_date seems to work for me:
WITH stg AS (
SELECT "9/9/2001" AS input_date
UNION ALL
SELECT "2021-01-01" AS input_date)
SELECT
CASE
WHEN safe.parse_DATE("%Y-%m-%d", input_date) IS NULL THEN
safe.parse_DATE("%d/%m/%Y", input_date)
ELSE safe.parse_DATE("%Y-%m-%d",input_date)
END AS output_date
FROM
stg
The table
becomes:
The logic is that: BQ tests one format and if it cannot make any sense of it, it tests the other format.
If none of them work the result is NULL.

Oracle use LIKE '%' on DATE

My table myTab has the column startDate, which has the datatype "DATE". The data in this column are stored like dd.mm.yyyy.
Now I'm trying to get data with this query:
SELECT * FROM myTab WHERE startDate like '%01.2015"
Somehow it doesn't work and I don't know why.
Hope someone can help.
To make a text search on the date you would have to convert the date to text.
It's more efficient if you calculate the first and last date for what you want to find and get everything between them. That way it's done as numeric comparisons instead of a text pattern match, and it can make use of an index if there is one:
SELECT * FROM myTab WHERE startDate >= DATE '2015-01-01' AND startDate < DATE '2015-02-01'
SELECT * FROM myTab WHERE TO_CHAR(startDate,'dd.mm.yyyy') LIKE '%01.2015'
If the field type is "DATE" then the value isn't stored as a string, it's a number managed by Oracle, so you have to convert it to a string:
SELECT * FROM myTab WHERE to_char(startDate, 'MM.YYYY') = '01.2015';
You can also use date ranges in SQL queries:
SELECT * FROM myTab
WHERE startDate
BETWEEN to_date('01.01.2015', 'DD.MM.YYYY')
AND to_date('31.01.2015', 'DD.MM.YYYY');
Regarding you actual question "Somehow it doesn't work and I don't know why."
Oracle make an implicit conversion from DATE to VARHCAR2, however it uses the default NLS_DATE_FORMAT which is probably different to what you use in your query.
The data in this column are stored like dd.mm.yyyy.
Oracle does not store date in the format you see. It stores it internally in proprietary format in 7 bytes with each byte storing different components of the datetime value.
WHERE startDate like '%01.2015"
You are comparing a DATE with a STRING, which is pointless.
From performance point of view, you should use a date range condition so that if there is any regular INDEX on the date column, it would be used.
SELECT * FROM table_name WHERE date_column BETWEEN DATE '2015-01-01' AND DATE '2015-02-01'
To understand why a Date range condition is better in terms of performance, have a look at my answer here.
I solved my problem that way. Thank you for suggestions for improvements. Example in C#.
string dd, mm, aa, trc, data;
dd = nData.Text.Substring(0, 2);
mm = nData.Text.Substring(3, 2);
aa = nData.Text.Substring(6, 4);
trc = "-";
data = aa + trc + mm + trc + dd;
"Select * From bdPedidos Where Data Like '%" + data + "%'";
To provide a more detailed answer and address this https://stackoverflow.com/a/42429550/1267661 answer's issue.
In Oracle a column of type "date" is not a number nor a string, it's a "datetime" value with year, month, day, hour, minute and seconds.
The default time is always midnight "00:00:00"
The query:
Select * From bdPedidos Where Data Like '%" + data + "%'"
won't work in all circumstances because a date column is not a string, using "like" forces Oracle to do a conversion from date value to string value.
The string value may be year-month-day-time or month-day-year-time or day-month-year-time, that all depends how a particular Oracle instance has set the parameter NLS_DATE_FORMAT to show dates as strings.
The right way to cover all the possible times in a day is:
Select *
From bdPedidos
Where Data between to_date('" + data + " 00:00:00','yyyy-mm-dd hh24:mi:ss')
and to_date('" + data + " 23:59:59','yyyy-mm-dd hh24:mi:ss')
SELECT * FROM myTab WHERE startDate like '%-%-2015';
This will search for all dates in 2015. If this doesn't work, try:
SELECT * FROM myTab WHERE startDate like '%-%-15';

How to query oracle dates properly?

select * from mytable where datecolumn == to_date('01-DEC-13','DD-MMM-YY')
I am getting the "ORA-01821: date format not recognized"
Where I do a query for a select * from mytable, I see that the values in datecolumn show up like "01-DEC-13" What am I doing wrong?
I'd recommend using the full century for dates. I've dealt with plenty of databases where somebody messed up the centuries because they didn't understand Oracle or the front-end language. Consider this for your 01-DEC-13 date:
CREATE TABLE LousyDates (DateVal DATE);
INSERT INTO LousyDates VALUES (DATE '2013-12-01');
INSERT INTO LousyDates VALUES (DATE '1713-12-01');
INSERT INTO LousyDates VALUES (TO_DATE('12/1/13 BC', 'MM/DD/YYYY BC'));
SELECT
TO_CHAR(DateVal, 'DD-MON-YY') AS NoCentury,
TO_CHAR(DateVal, 'MM/DD/YYYY BC') AS WithCentury
FROM LousyDates;
NOCENTURY WITHCENTURY
------------------ -------------
01-DEC-13 12/01/2013 AD
01-DEC-13 12/01/1713 AD
01-DEC-13 12/01/0013 BC
OK, maybe I'm overstating the point with the 13 BC date, but you get the idea :)
To use the century...
SELECT * FROM MyTable WHERE datecolumn = TO_DATE('01-DEC-2013', 'DD-MON-YYYY')
or
SELECT * FROM MyTable WHERE datecolumn = DATE '2013-12-01'
Unless you're 100% sure you will never ever use different language settings, I'd recommend using MM instead of MON:
select * from mytable where datecolumn = to_date('2013-12-01', 'YYYY-MM-DD')
This will work with any NLS settings, whereas comparing the output of to_date(...MON...) with 'DEC' will fail utterly on different locales.
Try this:
SELECT * from MYTABLE WHERE TO_CHAR(datecolumn,'DD-MON-YY') == '01-DEC-13'
instead of converting your wildcard, try to convert your datetime.

Using a variable in an SQL query (Oracle DBMS)?

I am typing SQL queries to get some data from a software tool which is based on an Oracle database. I am using the typical SELECT-statement.
Now, in my SQL-query I am using at different places the date "02.05.2012". Is there a way to define a variable date_string at the beginning and then use at all relevant places this variable?
This would simplify things a lot. Thanks for all hints and tips!
You might try to rewrite your query to return the literal from an inline view ...
select
my_date,
...
from(
select to_date('02.05.2012','DD.MM.YYYY') my_date from dual),
table2
where
some_column <= my_date
What you look for is a bind variable.
select to-date(:date, 'dd.mm.yyyy') date1
, to-date(:date, 'dd.mm.yyyy') + 1 date2
from dual
On runtime you need to pass the value to the bind variable. It all depends on your programming language how to bind the variable, but there is plenty documentation for that.
DEFINE only works if you use sql*plus, and that's usually not the case inside a "software tool" :)
EDIT:
I'm beginning to understand now. It's just a textarea where you can enter a query and it will execute it and return the result. In that case you either write some complicated pl/sql code, or enter all the dates manually, or use a cross join with a select from dual:
with (select to_date('02.05.2012', 'dd.mm.yyyy') my_date from dual) d
select *
from some_table t
cross join d -- no ON required
If you want to select using the current date you can use sysdate.
Using SQLPLUS you can define your own variables:
SQL> define mydate ="01-05-2012"
SQL> select to_date('&mydate','DD-MM-YYYY') from dual;
01-MAY-12
try the following :
SELECT *
FROM table1
WHERE to_char(date1,'DD/MM/YYYY') = '&&date'
AND to_char(date2,'DD/MM/YYYY') = '&&date'
AND to_char(date3,'DD/MM/YYYY') = '&&date'
you will get a prompt to enter the value for the &&date , if you want to enter different values for each date, you should type &date instead of &&date
DEFINE is useful for your requirement.
DEFINE NAME="example"
access with &NAME

How to get one day ahead of a given date?

Suppose I have a date 2010-07-29. Now I would like to check the result of one day ahead. how to do that
For example,
SELECT *
from table
where date = date("2010-07-29")
How to do one day before without changing the string "2010-07-29"?
I searched and get some suggestion from web and I tried
SELECT *
from table
where date = (date("2010-07-29") - 1 Day)
but failed.
MySQL
SELECT *
FROM TABLE t
WHERE t.date BETWEEN DATE_SUB('2010-07-29', INTERVAL 1 DAY)
AND '2010-07-29'
Change DATE_SUB to DATE_ADD if you want to add a day (and reverse the BETWEEN parameters).
SQL Server
SELECT *
FROM TABLE t
WHERE t.date BETWEEN DATEADD(dd, -1, '2010-07-29')
AND '2010-07-29'
Oracle
SELECT *
FROM TABLE t
WHERE t.date BETWEEN TO_DATE('2010-07-29', 'YYYY-MM-DD') - 1
AND TO_DATE('2010-07-29', 'YYYY-MM-DD')
I used BETWEEN because the date column is likely DATETIME (on MySQL & SQL Server, vs DATE on Oracle), which includes the time portion so equals means the value has to equal exactly. These queries give you the span of a day.
If you're using Oracle, you can use the + and - operators to add a number of days to a date.
http://psoug.org/reference/date_func.html
Example:
SELECT SYSDATE + 1 FROM dual;
Will yield tomorrow's date.
If you're not using Oracle, please tell use what you ARE using so we can give better answers. This sort of thing depends on the database you are using. It will NOT be the same across different databases.
Depends of the DateTime Functions available on the RDBMS
For Mysql you can try:
mysql> SELECT DATE_ADD('1997-12-31',
-> INTERVAL 1 DAY);
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
-> '1997-12-02'
If youre using MSSQL, you're looking for DateAdd() I'm a little fuzzy on the syntax, but its something like:
Select * //not really, call out your columns
From [table]
Where date = DateAdd(dd, -1, "2010-07-29",)
Edit: This syntax should be correct: it has been updated in response to a comment.
I may have the specific parameters in the wrong order, but that should get you there.
In PL SQL : select sysdate+1 from dual;