two results when i use oracle date - sql

i am running below sql in sql developer:
SELECT count(*)
from FTTH_AMS_DEVICE_METRICS DAT
where TRUNC(DAT.COLLECTION_TMS)>(select start_dt from ETL_JOB_CONTROL where job_name='s_m_ftth_prfrm_fact_tbl')
and TRUNC(DAT.COLLECTION_TMS)<=(select end_dt from ETL_JOB_CONTROL where job_name='s_m_ftth_prfrm_fact_tbl')
i get 38 million rows.
when i use hardcoded values in filter as below and run the query:
SELECT count(*)
from FTTH_AMS_DEVICE_METRICS DAT
where TRUNC(DAT.COLLECTION_TMS)> TO_DATE('10-14-2016','MM-DD-YYYY')
and TRUNC(DAT.COLLECTION_TMS)<= TO_DATE('10-15-2016','MM-DD-YYYY')
i am getting 12 million rows.
because i pass the date values through parameter files in informatica.
I am very much confused how to handle this and get 38 million rows when i run in Informatica.
data type for COLLECTION_TMS is timestamp and end_dt is datetime.
if you need more information on this, i will share immediately.
Thanks for your help.

If the dates are exactly as you show them, then in the second query you should have > to_date ('10-15-2016', 'mm-dd-yyyy') and <= to_date('10-16-2016', 'mm-dd-yyyy'). You are comparing to the wrong dates.

The following is speculation, informed speculation. The date data type in Oracle supports a time component. However, when you print out the date, often the time component is removed.
I am guessing that the values in start_dt and end_dt in ETL_JOB_CONTROL have time components.
If so, the following query should return at least 38 million:
select count(*)
from FTTH_AMS_DEVICE_METRICS DAT
where TRUNC(DAT.COLLECTION_TMS) > TO_DATE('10-14-2016', 'MM-DD-YYYY') and
TRUNC(DAT.COLLECTION_TMS) <= TO_DATE('10-16-2016', 'MM-DD-YYYY');
If this is the case, then just determine the full value for the two columns and use that:
select to_char(start_dt, 'YYYY-MM-DD HH24:MI:SS'),
to_char(end_dt, 'YYYY-MM-DD HH24:MI:SS')
from ETL_JOB_CONTROL;

Related

SQL Query required ot get records count on hourly basis

I am trying to get records from 29th April,2022 on hourly basis from Oracle DB, however with the below query I am getting records count older than 29th April as well(all previous records count as well). Can you help fine tune the query?
SELECT DISTINCT
COUNT(*),
STATUS,
TO_CHAR(LOAD_DATE,'DD-MON-YY HH24')
FROM
TARGET_HIST
WHERE
STATUS = 'A'
AND TO_CHAR(LOAD_DATE, 'DD-MON-YY HH24:MI:SS') > '29-APR-22 00:00:00'
GROUP BY
STATUS,
TO_CHAR(LOAD_DATE,'DD-MON-YY HH24')
ORDER BY
STATUS,
TO_CHAR(LOAD_DATE,'DD-MON-YY HH24');
Try this. Since you didn't provide any sample data I didn't test it for you
select trunc(load_date,'HH') "HOUR", count(*)
from target_hist
where status='A' AND
load_date between to_date('29/04/2022','DD/MM/YYYY') and to_date('29/04/2022 23:59:59','DD/MM/YYYY HH24:MI:SS');
Group by trunc(load_date,'HH')
Order by trunc(load_date,'HH')
Two problem with the same reason:
In your WHERE clause you look for rows after '29-APR-22 00:00:00', but you get rows before that.
In your ORDER BY clause you get the dates sorted in a mangled order.
This is because you have converted the datetimes to strings where '29-APR-22' comes after '01-MAY-22', but before '30-JAN-22', because '2' comes after '1' and before '3'.
If you want to sort and compare datetimes, then use datetimes. You can truncate them down to the hour with TRUNC(load_date, 'hh').
select
trunc(load_date, 'hh') as load_hour,
status,
count(*)
from target_hist
where status = 'A'
and load_date >= date '2022-04-29'
group by trunc(load_date, 'hh'), status
order by trunc(load_date, 'hh'), status;
Leave it to your app to display the datetime in the format the user wants to see it. If you need a particular format, e.g. for exporting the data into a file, you can apply TO_CHAR on the truncated datetime TO_CHAR(trunc(load_date, 'hh'),'DD-MON-YY HH24') in the select clause (and only there).
Please note that I have removed DISTINCT from the query, because there are no duplicates to remove. And I am using a date literal in the WHERE clause. And >=in order to include midnight.
This query considers all days since April 29. If you want this day only, then add and load_date < date '2022-04-30'.

What should be the outcome of TRUNC('02-MAY-14','HH24')?

I found a bizarre snippet which is confusing me so I thought I'll ask the experts.
Let assume a tableA got following columns with data:
"START_TIME":1399075198
"END_TIME":1399075200
"START_DATE":"02-MAY-14"
"END_DATE":"03-MAY-14"
Now query 1:
SELECT MIN(start_date) INTO sdate FROM tableA;
query 2:
SELECT TRUNC(sdate, 'HH24') + INTERVAL '30' MINUTE from dual;
So if start-date = '02-MAY-14', how would that truncate to 'HH24'?
The expression:
TRUNC(sdate, 'HH24')
cuts off everything from a date that is smaller than an hour, i.e. the minutes and seconds. For the specific date:
TRUNC('02-MAY-14','HH24')
it returns the date unchanged. It only makes sense if the Oracle date contains a time component.
Possibly, your SQL tool (SQL Developer, TOAD etc.) is configured to not display the time part of Oracle dates. So the original date might in fact be 02-MAY-14 09:03:25. Then it would return:
02-MAY-14 09:00:00
You mention the columns START_TIME and END_TIME but don't use them in the SQL queries. What are they for?
As start_date does not have a time part in your example, TRUNC is superfluous here. If however it had a timepart, if for example start_time had been added to start_date before, then TRUNC would remove minutes, seconds and microseconds, only keeping the date and hour because of 'HH24' which means "truncate datetime down to full hour".
In Oracle the date datatype inherently store the time as well.
Try executing the below query. It should clear things up a bit:
SELECT TO_CHAR(SYSDATE,'DD-MON-YYYY HH:MI:SS'), TO_CHAR(TRUNC(SYSDATE,'HH24'),'DD-MON-YYYY HH:MI:SS') FROM DUAL;

Compare two dates based on timestamp on Oracle 11g

Am dealing with two tables A and B on Oracle 11g and trying to compare records (A.TRANSACTION_TIMESTAMP and B.LAST_TRANSACTION_TIMESTAMP) based on timestamp on columns with datatype DATE
Based on what i have tried, the below query does not give the expected output and returns records even when TRANSACTION_TIMESTAMP is less than LAST_TRANSACTION_TIMESTAMP
TO_CHAR(TRANSACTION_TIMESTAMP, 'DD-MON-YYYY HH24:MI:SS') >=
(SELECT TO_CHAR(LAST_TRANSACTION_TIMESTAMP, 'DD-MON-YYYY HH24:MI:SS')
FROM LAST_RAN_TIME)
Would highly appreciate if anyone can provide some inputs on comparing Dates with timestamp on Oracle 11g
Do not convert with TO_CHAR. Just compare columns directly.
The comparision is failing because you are using strings that start with the day!
TRANSACTION_TIMESTAMP >= (SELECT LAST_TRANSACTION_TIMESTAMP FROM LAST_RAN_TIME)

Select from table by knowing only date without time (ORACLE)

I'm trying to retrieve records from table by knowing the date in column contains date and time.
Suppose I have table called t1 which contains only two column name and date respectively.
The data stored in column date like this 8/3/2010 12:34:20 PM.
I want to retrieve this record by this query for example (note I don't put the time):
Select * From t1 Where date="8/3/2010"
This query give me nothing !
How can I retrieve date by knowing only date without the time?
DATE is a reserved keyword in Oracle, so I'm using column-name your_date instead.
If you have an index on your_date, I would use
WHERE your_date >= TO_DATE('2010-08-03', 'YYYY-MM-DD')
AND your_date < TO_DATE('2010-08-04', 'YYYY-MM-DD')
or BETWEEN:
WHERE your_date BETWEEN TO_DATE('2010-08-03', 'YYYY-MM-DD')
AND TO_DATE('2010-08-03 23:59:59', 'YYYY-MM-DD HH24:MI:SS')
If there is no index or if there are not too many records
WHERE TRUNC(your_date) = TO_DATE('2010-08-03', 'YYYY-MM-DD')
should be sufficient. TRUNC without parameter removes hours, minutes and seconds from a DATE.
If performance really matters, consider putting a Function Based Index on that column:
CREATE INDEX trunc_date_idx ON t1(TRUNC(your_date));
Personally, I usually go with:
select *
from t1
where date between trunc( :somedate ) -- 00:00:00
and trunc( :somedate ) + .99999 -- 23:59:59
Convert your date column to the correct format and compare:
SELECT * From my_table WHERE to_char(my_table.my_date_col,'MM/dd/yyyy') = '8/3/2010'
This part
to_char(my_table.my_date_col,'MM/dd/yyyy')
Will result in string '8/3/2010'
You could use the between function to get all records between 2010-08-03 00:00:00:000 AND 2010-08-03 23:59:59:000
trunc(my_date,'DD') will give you just the date and not the time in Oracle.
Simply use this one:
select * from t1 where to_date(date_column)='8/3/2010'
Try the following way.
Select * from t1 where date(col_name)="8/3/2010"

how to use = assignment operator with timestamp date column in oracle

I'm using timestamp in dat column in table r3. when I fire command
select dat from r3 where dat='16-nov-09';
it shows "no rows selected" but when i fire command
select dat from r3 where dat>'15-nov-09';
it shows the whole data of 16-nov-09. Tell me what is wrong in my first command or what i have to do.
Quering on oracle date columns is always confusing. The date columntype is always a datetime. Storing the current date from sysdate stores always the time component too.
There good and evil ways quering the date columns. I show and vote some.
where to_char(DAT, 'DD-MON-YYYY') = '16-NOV-2009'
where trunc(DAT) = to_date('16-NOV-2009', 'DD-MON-YYYY')
Both bad, because they do not use any index. To avoid this, you can define a function based index on the expression.
The trick of both is to cut off the time component. If time is not needed, than it is a good advise to cut off the time in INSERT and UPDATE trigger. The function based index can convert to a normal index.
where DAT between to_date('16-NOV-2009', 'DD-MON-YYYY')
and to_date('16-NOV-2009 23:59:59', 'DD-MON-YYYY HH24:MI:SS')
where DAT >= to_date('16-NOV-2009', 'DD-MON-YYYY') and DAT < to_date('16-NOV-2009', 'DD-MON-YYYY')+1
This two are always my favorites.
Its a good advice to use to_date and to_char to convert the values between string and datetime.
As DAT is timestamp you can use as below
select DAT from R3
where DAT between to_date('16-NOV-09' , 'dd-MON-yy') and to_date('16-NOV-09 23:59:59', 'DD-MON-YY hh24:mi:ss')
Timestamp has time and date components, so query
select dat from r3 where dat='16-nov-09';
will work only for records where time component is midnight: '00:00:00'
Beside formatting (to_date function), you can truncate timestamp to get only date:
select dat from r3 where trunc(dat)='16-nov-09';
Beware that this will not use index on field dat (if there is any).
TIMESTAMP and DATE are different data types in oracle and both store time components. If you really do need to store subsecond times then you use TIMESTAMP, otherwise DATE is your best choice.
The ANSI timestamp and date literal syntaxes are quite handy:
create table ts_test (ts1 timestamp);
select *
from ts_test
where ts1 > timestamp '2009-10-11 00:00:00'
/
select *
from ts_test
where ts1 > timestamp '2009-10-11 00:00:00.1'
/
select *
from ts_test
where ts1 > timestamp '2009-10-11 00:00:00.001'
/
select *
from ts_test
where ts1 = date '2009-10-11'
/
use the below format for a date field in where condition.
where to_char(DAT,'mmddyyyy') = '11152009';
In Oracle the date fields also contain a time component, so 16-nov-09 is actually midnight of Nov 16th.
Two different ways to handle this:
where to_char(DAT,'mmddyyyy') = '11152009'
as john suggested, but I like the following version more:
where trunc(dat) = to_date ('11152009', 'mmddyyyy')
TRUNCfor a date "removes" the time component (or to be more specific, truncates it to midnight), and to_date is the proper way to construct a date value in Oracle SQL. (I prefer to do the comparisons in the right domain - DATEs as in the second example- over another - STRINGs as in the first example. With strings you may run into some weird month issues, sorting is easier in dates etc.)
Just to add to it , An easy way out when you are not bothered about the time-stamp but just want to compare the date is to use the 'like' operator.
for example
select dat from r3 where dat LIKE '16-nov-09%'
will give you desired output.