This question already has answers here:
Equals(=) vs. LIKE for date data type
(3 answers)
Closed 5 years ago.
Query 1 :
select count(*) from CI_TXN_HEADER where TXN_HEADER_DTTM = '25-JAN-13';
Result: 1
Query 2 :
select count(*) from CI_TXN_HEADER where TXN_HEADER_DTTM like '25-JAN-13';
Result: 19
In my DB I have 19 rows with TXN_HEADER_DTTM as 25-JAN-13.
Data Type of TXN_HEADER_DTTM is DATE.
Can someone please explain the difference in output?
An Oracle DATE column contains a date and a time. The LIKE condition is only for VARCHAR columns. If applied to other data types Oracle implicitly converts that to a varchar (using rules depending on the current client settings).
So you might have rows with e.g. 2013-01-25 17:42:01, however the string constant '25-JAN-13' is (most probably) converted to: 2013-01-25 00:00:00 and thus the = comparison doesn't work.
To find all rows for a specific day use trunc() and a proper date literal. Don't rely on the evil implicit data type conversion to specify date values.
Use trunc() to set the time part of a DATE value to 00:00:00:
I prefer ANSI SQL date literals:
select count(*)
from CI_TXN_HEADER
where trunc(TXN_HEADER_DTTM) = DATE '2013-01-25';
You can also use Oracle's to_date:
select count(*)
from CI_TXN_HEADER
where trunc(TXN_HEADER_DTTM) = to_date('2013-01-25', 'yyyy-mm-dd');
Note that Oracle can't use an index on TXN_HEADER_DTT, so if performance is critical use a range query:
select count(*)
from CI_TXN_HEADER
where TXN_HEADER_DTTM >= DATE '2013-01-25'
and TXN_HEADER_DTTM < DATE '2013-01-25' + 1;
The difference between like and equal is explained in this link very good
https://stackoverflow.com/a/2336940/4506285
I checked your problem on my table and I get the same results.
This link helps also to understand how to compare dates in sql
https://stackoverflow.com/a/18505739/4506285
Maybe your data consists of space, it is not exactly '25-JAN-13' but ' 25-JAN-13';
Please refer this two link:
Equals(=) vs. LIKE
What's the difference between "LIKE" and "=" in SQL?
Related
This question already has an answer here:
Query to compare between date with time and date without time - python using access db
(1 answer)
Closed 4 years ago.
I need to select records with DateTime between two dates in an Access query. The problem is that when I'm execute this query:
select * from logs
where date_added >= CDate("01/10/2018")
AND date_added <= CDate("04/10/2018")
I need both border values but the result does not include the last day. Maybe because "04/10/2018" is converted to "04/10/2018 00:00:00" and this value is less than all date_added values of that day.
Can I convert date_added to date only?
Do you can add a day to your date?
AND date_added < DateAdd('d',1,CDate("04/10/2018"))
An alternative expression:
SELECT * FROM logs
WHERE DateValue(date_added) BETWEEN #01/10/2018# AND #4/10/2018#
Useful date functions and syntax:
Date literals can be delimited with # in both VBA code and SQL statements, so you don't have to call CDate() on string values. Examples: #10/6/2018 4:16 PM#, #1/1/2018#
Simple mathematical notation can be used to add and subtract whole days from a date value. Example: #10/6/2018# + 1 == #10/7/2018#
DateValue( val ) takes arguments of various formats and returns a date/time value with only the date portion. This answers your question Can I convert date_added to date only? It essentially returns the same date value with the time portion as 00:00:00.
Example: DateValue(#10/6/2018 4:16 PM#) == #10/6/2018#
DateAdd ( interval, number, date ) as already noted by Milad Aghamohammadi.
Within SQL only (not VBA), one can use the BETWEEN operator. It works with various data types that have a natural sort order, which includes date values.
Example ... WHERE [DateField] BETWEEN #1/1/2018# AND #4/1/2018#
I'm having issues with what I assumed would be a simple problem, but googling isn't helping a great load. Possibly I'm bad at what I am searching for nether the less.
SELECT ORDER_NUMB, CUSTOMER_NUMB, ORDER_DATE
FROM ORDERS
WHERE FORMAT(ORDER_DATE, 'DD-MMM-YYYY') = '07-JUN-2000';
It tells me I am using an invalid identifier. I have tried using MON instead of MMM, but that doesn't help either.
Unsure if it makes any difference but I am using Oracle SQL Developer.
There are multiple issues related to your DATE usage:
WHERE FORMAT(ORDER_DATE, 'DD-MMM-YYYY') = '07-JUN-2000';
FORMAT is not an Oracle supported built-in function.
Never ever compare a STRING with DATE. You might just be lucky, however, you force Oracle to do an implicit data type conversion based on your locale-specific NLS settings. You must avoid it. Always use TO_DATE to explicitly convert string to date.
WHERE ORDER_DATE = TO_DATE('07-JUN-2000','DD-MON-YYYY','NLS_DATE_LANGUAGE=ENGLISH');
When you are dealing only with date without the time portion, then better use the ANSI DATE Literal.
WHERE ORDER_DATE = DATE '2000-06-07';
Read more about DateTime literals in documentation.
Update
It think it would be helpful to add some more information about DATE.
Oracle does not store dates in the format you see. It stores it
internally in a proprietary format in 7 bytes with each byte storing
different components of the datetime value.
BYTE Meaning
---- -------
1 Century -- stored in excess-100 notation
2 Year -- " "
3 Month -- stored in 0 base notation
4 Day -- " "
5 Hour -- stored in excess-1 notation
6 Minute -- " "
7 Second -- " "
Remember,
To display : Use TO_CHAR
Any date arithmetic/comparison : Use TO_DATE
Performance Bottleneck:
Let's say you have a regular B-Tree index on a date column. now, the following filter predicate will never use the index due to TO_CHAR function:
WHERE TO_CHAR(ORDER_DATE, 'DD-MM-YYYY') = '07-06-2000';
So, the use of TO_CHAR in above query is completely meaningless as it does not compare dates, nor does it delivers good performance.
Correct method:
The correct way to do the date comparison is:
WHERE ORDER_DATE = TO_DATE('07-JUN-2000','DD-MON-YYYY','NLS_DATE_LANGUAGE=ENGLISH');
It will use the index on the ORDER_DATE column, so it will much better in terms of performance. Also, it is comparing dates and not strings.
As I already said, when you do not have the time element in your date, then you could use ANSI date literal which is NLS independent and also less to code.
WHERE ORDER_DATE = DATE '2000-06-07';
It uses a fixed format 'YYYY-MM-DD'.
try this:
SELECT ORDER_NUMB, CUSTOMER_NUMB, ORDER_DATE
FROM ORDERS
WHERE trunc(to_date(ORDER_DATE, 'DD-MMM-YYYY')) = trunc(to_date('07-JUN-2000'));
I do not recognize FORMAT as an oracle function.
I think you meant TO_CHAR.
SELECT ORDER_NUMB, CUSTOMER_NUMB, ORDER_DATE
FROM ORDERS
WHERE TO_CHAR(ORDER_DATE, 'DD-MMM-YYYY') = '07-JUN-2000';
try to_char(order_date, 'DD-MON-YYYY')
I am trying to check for dates but after running the query below, it displays no result. Could someone recommend me the correct syntax?
SELECT TOP 10 * FROM MY_DATABASE.AGREEMENT
WHERE end_dt=12/31/9999
12/31/9999 might look like a date for you but for the database it's a calculation:
12 divided by 31 divided by 9999 and because this involves INTEGER division this results in an INTEGER 0
So finally you compare a DATE to an INT and this results in typecasting the DATE to a INT.
The only reliable way to write a date literal in Teradata is DATE followed by a string with a YYYY-MM-DD format:
DATE '9999-12-31'
Similar for TIME '12:34:56.1' and TIMESTAMP '2014-08-20 12:34:56.1'
Is it a date column? Then try where end_dt = '9999-12-31'.
The question you ask is not very clear. The date you specify is language dependent.
Try
SELECT TOP 10 * FROM MY_DATABASE.AGREEMENT WHERE end_dt='99991231'
I have a table X with 'insert_date' column. This column is od type DATE and contains only one value for all records: "17-JAN-13". I would expect that following query return no results at all:
SELECT insert_date
FROM X
WHERE ("X"."INSERT_DATE" IS NOT NULL
AND NOT (("X"."INSERT_DATE" = to_date('2013-01-17', 'yyyy-mm-dd')
)))
But what I'm getting instead is many "17-JAN-13" records.
What's wrong with my query?
Oracle DATE columns contain a time as well (despite their name). Your existing rows probably have a time different than 00:00:00 (which is "assigned" to the date you create with the to_date() function).
You need to "remove" the time part of the column using trunc()
AND NOT (trunc(X.INSERT_DATE) = to_date('2013-01-17', 'yyyy-mm-dd'))
although I'd prefer to use <> instead of the NOT operator:
AND (trunc(X.INSERT_DATE) <> to_date('2013-01-17', 'yyyy-mm-dd'))
(but that is just a personal preference. I think it makes the condition easier to read).
So your complete statement would be:
SELECT insert_date
FROM X
WHERE trunc(X.INSERT_DATE) <> to_date('2013-01-17', 'yyyy-mm-dd')
You can either trunc the time part while comparing or else extract only the required part i.e DD-MON-YYYY like
SELECT insert_date FROM X
WHERE X.INSERT_DATE IS NOT NULL and to_char(x.INSERT_DATE,'DD-MON-YYYY') <> '17-JAN-2013';
Thanks for your help. I am not able to make out the type/format of the "Value" in a Date column.I guess its in Julian Date format.
The Column is paid_month and the values are below.
200901
200902
So,please help in writing SQL query to convert the above values(Mostly in Julian Format) in the Date Column to normal date (MM/DD/YYYY) .
Thanks
Rohit
Hi,
I am sorry for missing in giving the whole information.
1)Its a Oracle Database.
2)The column given is Paid_Month with values 200901,200902
3)I am also confused that the above value gives month & year.Day isnt given if my guess is right.
4)If its not in Julian format ,then also please help me the SQL to get at least mm/yyyy
I am using a Oracle DB and running the query
THANKS i GOT THE ANSWER.
**Now,i have to do the reverse meaning converting a date 01/09/2010 to a String which has 6 digits.
Pls help with syntax-
select to_char(01/01/2010,**
It looks like YYYYMM - depending on your database variant, try STR_TO_DATE(paid_month, 'YYYYMM'), then format that.
Note: MM/DD/YYYY is not "normal" format - only Americans use it. The rest of the world uses DD/MM/YYYY
For MySQL check
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date-format
Example:
SELECT DATE_FORMAT(NOW(), '%d/%m/%Y')
For MySQL, you would use the STR_TO_DATE function, see http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_str-to-date
SELECT STR_TO_DATE(paid_month,'%Y%m');
Sounds like the column contains some normal dates and some YYYYMM dates. If the goal is to update the entire column, you can attempt to isolate the YYYYMM dates and update only those. Something like:
UPDATE YourTable
SET paid_month = DATE_FORMAT(STR_TO_DATE(paid_month, '%Y%m'), '%m/%d/%Y')
WHERE LENGTH(paid_month) = 6
SELECT (paid_month % 100) + "/01/" + (paid_month/100) AS paid_day
FROM tbl;
I'm not sure about how oracle concatenates strings. Often, you see || in SQL:
SELECT foo || bar FROM ...
or functions:
SELECT cat (foo, bar) FROM ...