oracle 检索相同值作为差异比较

5jvtdoz2  于 2022-12-11  发布在  Oracle
关注(0)|答案(1)|浏览(118)

I am trying to compare the date fields between two of my tables T1 and T2.
I have framed a query similar to below and doing the comparison:

Query:

SELECT distinct t1.id t1_id, t2.id t2_id, t1.source t1_source, t2.source t2_source, to_date(t1.t1_date,'MM-DD-YYYY') t1_date, to_char(t2.t2_date,'DD-MON-YY')  t2_date
FROM t1
JOIN t2 ON t1.id=t2.id
AND t1.source = t2.source
and to_date(t1.t1_date,'MM-DD-YYYY') <> to_char(t2.t2_date,'DD-MON-YY');

Though the T1_DATE and T2_DATE are one and the same, the results are popping up that they are not equal.

------------------------------------------------------------------------
T1_ID    |  T2_ID    |  T2_SOURCE | T2_SOURCE | T1_DATE   | T2_DATE
------------------------------------------------------------------------
123      |  123      |  SOU       | SOU      |  17-FEB-47 | 17-FEB-47
234      |  234      |  SOU       | SOU      |  01-JAN-49 | 01-JAN-49
------------------------------------------------------------------------
  • I did copy pasted T1_DATE and T2_DATE to notepad and confirmed that they don't have any leading or trailing spaces.
  • I verified from the table that they don't have any leading or trailing spaces.
  • The date condition I added for comparison too doesn't have any spaces.

I now updated my query to add trim to my condition:

Updated query:

SELECT distinct t1.id t1_id, t2.id t2_id, t1.source t1_source, t2.source t2_source, to_date(t1.t1_date,'MM-DD-YYYY') t1_date, to_char(t2.t2_date,'DD-MON-YY')  t2_date
FROM t1
JOIN t2 ON t1.id=t2.id
AND t1.source = t2.source
and trim(to_date(t1.t1_date,'MM-DD-YYYY')) <> trim(to_char(t2.t2_date,'DD-MON-YY'));

And now it worked fine. What is happening in the backend?
Please advice.

sr4lhrrt

sr4lhrrt1#

When you compare with:

to_date(t1.t1_date,'MM-DD-YYYY') <> to_char(t2.t2_date,'DD-MON-YY');

you are comparing a date on the left-hand side with a string on the right-hand side. That is forcing Oracle to do an implicit conversion so that they are both the same data type, to allow the values to be compared.
The data comparison rules say:

  • When comparing a character value with a DATE value, Oracle converts the character data to DATE.

So the string you just generated is converted back to a date, so you're really doing:

to_date(t1.t1_date,'MM-DD-YYYY') <> to_date(to_char(t2.t2_date,'DD-MON-YY'))

... which used your NLS settings, and your NLS_DATE_FORMAT appears to be DD-MON-YY too. The string is going to be '17-FEB-47', and when you convert that back to a date with the two-digit YY format mask that uses the current century, so it comes out as 2047, not 1947. So you end up effectively doing:

date '1947-02-17' <> date '2047-02-17'

... which is true, as the dates are in different centuries, hence your rows are displayed.
But when you do:

trim(to_date(t1.t1_date,'MM-DD-YYYY')) <> trim(to_char(t2.t2_date,'DD-MON-YY'))

you are now comparing two strings. The left-hand side is converted to a date and now that is implicitly converted back to a string, again using your NLS setting, and the right-hand side isn't modified. So you end up effectively doing:

'17-FEB-47' <> '17-FEB-47'

... which is false, so the rows are not shown.
So, either leave the right-hand side as its original date value:

to_date(t1.t1_date,'MM-DD-YYYY') <> t2.t2_date

or if that has a time part you want to ignore then truncate it, but leave it as a date:

to_date(t1.t1_date,'MM-DD-YYYY') <> trunc(t2.t2_date)

fiddle

相关问题