sql query to fetch records between current date and minimum date - sql

I am writing this sql query but it says now non-numeric character was found where a numeric was expected.Where is the mistake??
SELECT dr.*
from daily_data_reading dr
where pod_id='01611152005960'
and DAILY_READING_DATE BETWEEN to_date(' min(daily_reading_date)','DD-MM-YY HH24:MI:SS')+ interval '1' day
AND to_date('trunc(SYSDATE) 23:59:59','DD-MM-YY HH24:MI:SS') + interval '1' day;

You are using to_date() in the wrong way
It makes no sense to call to_date() on a date value to convert that date value to a date.
Also to_date() expects a string formatted as a valid date.
Neither 'min(daily_reading_date)' nor 'trunc(SYSDATE) 23:59:59' is a valid date string.
So
to_date('min(daily_reading_date)','DD-MM-YY HH24:MI:SS')+ interval '1' day
needs to be:
min(daily_reading_date) + interval '1' day
And
to_date('trunc(SYSDATE) 23:59:59','DD-MM-YY HH24:MI:SS') + interval '1' day
should be:
AND trunc(SYSDATE) + interval '1' day
So your complete query should be:
SELECT dr.*
from daily_data_reading dr
where pod_id = '01611152005960'
and DAILY_READING_DATE BETWEEN min(daily_reading_date) + interval '1' day
AND trunc(SYSDATE) + interval '1' day;
But the above query will just trigger the next error: you can't use min(daily_reading_date) without applying a group by clause.
But you should ask a new question for that - including sample data and table definitions.

Related

How to substract 2 varchar dates in oracle?

I have these varchar : 20211026231735.
So I would like a query to substract actual sysdate to that date and convert the substraction to DAY HOURS AND SECONDS.
select TO_CHAR(SYSDATE,'YYYYMMDDHH24MISS') - start_time from TABLEA where job_name='jOB_AA_BB';
I get 4220.
Any help please? Thanks
When you do datetime arithmetic with the DATE datatype, you get back a NUMBER of days. To get an INTERVAL you can subtract two TIMESTAMPs. You don't say what the data type is for start_time, but you might get away with this:
select localtimestamp - start_time
from tablea where job_name='jOB_AA_BB';
LOCALTIMESTAMP gives you a TIMESTAMP value in the current session time zone. There's also CURRENT_TIMESTAMP, which give you the same thing in a TIMESTAMP WITH TIME ZONE and SYSTIMESTAMP that gives you the database time in TIMESTAMP WITH TIME ZONE. You may need to convert your start_time to avoid time zone differences, if any.
You can us the function numtodsinterval to convert the results of date arithmetic to an interval. If necessary then use extract to pull out the needed components.
with tablea(job_name, start_time) as
(select 'jOB_AA_BB','20211026231735' from dual)
select numtodsinterval((SYSDATE - to_date( start_time,'yyyymmddhh24miss')),'hour') date_diff
from tablea where job_name='jOB_AA_BB' ;
with tablea(job_name, start_time) as
(select 'jOB_AA_BB','20211026231735' from dual)
select extract (hour from date_diff) || ':' || extract (minute from date_diff)
from (
select numtodsinterval((sysdate - to_date( start_time,'yyyymmddhh24miss')),'day') date_diff
from tablea where job_name='jOB_AA_BB'
);
NOTE: I am not sure how you got any result, other than an error, as your query winds up as a string - a string. You should not convert sysdate to a string but your string to a date (better yet store it as the proper data type - date).
You can convert the value to a date (rather than converting SYSDATE to a string) and then subtract and explicitly return the value as an INTERVAL DAY TO SECOND type:
SELECT (SYSDATE - TO_DATE('20211026231735', 'YYYYMMDDHH24MISS')) DAY TO SECOND
FROM DUAL;
Or, for your table:
SELECT (SYSDATE - TO_DATE(start_time,'YYYYMMDDHH24MISS')) DAY(5) TO SECOND
FROM TABLEA
WHERE job_name='jOB_AA_BB';
db<>fiddle here

Sysdate in where clause not working in oracle sql

I have below select query where i am trying to get the data only for today date but its not returning anything:
select * from V_TER
where SYSTEM_INSERTED_AT = SYSDATE;
The SYSTEM_INSERTED_DATE is of Date datatype and the value is stored in this fields as for example 2021-01-15 15:17:13
The problem in Oracle is that dates can have time components both in the data and sysdate itself.
I would recommend checking for any time on the current date:
where system_inserted_at >= trunc(sysdate) and
system_inserted_at < trunc(sysdate) + interval '1' day
This is generally optimizer-friendly. If you don't care about that, then:
where trunc(system_inserted_at) = trunc(sysdate)

PostgreSQL convert month string to start and end dates of month

Is it possible to convert e.g. string "201701" to dates '2017-01-01' and '2017-01-31' in PostgreSQL?
So for:
"201701" get '2017-01-01' and '2017-01-31'
"201702" get '2017-02-01' and '2017-02-28'
"201703" get '2017-03-01' and '2017-02-31'
etc
You may use the TO_DATE function, and append the day component using string concatenation, something like this:
SELECT
TO_DATE('201702' || '01', 'YYYYMMDD') AS first,
(TO_DATE('201702' || '01', 'YYYYMMDD') + INTERVAL '1 month') -
INTERVAL '1 day' AS last;
The above trick just adds 01 to form the first of the month. For the last day of the same month, it first adds one month to the first, to get the first of the next month, then rolls back one day to get the last of the current month.
Demo
The above answer by Tim Biegeleisen works, but here's an alternative.
The to_date() function converts a string literal to a date value.
sample usage is : to_date(text,format);
SELECT to_date('201701','YYYYMMDD');
(EDITED)
You can also use date_trunc which is a part of PostgreSQL. It does the same as the above one.
select date_trunc('month', current_date) , date_trunc('month', CURRENT_DATE) + interval '1 month - 1 day';
Code Example Live Demo

Select data between timestamps

Usecase: Query to select the records for a whole day and it should run regularly.
This is my query.
Select to_char(in_date + interval '12' hour, 'DD-MON-YYYY HH24:MI:SS')
from my_table
where incoming_date > sysdate-2 and incoming_date < sysdate
I need to select yesterday's data only. Because of the conversion in the select statement I got today's data also. How do I select only yesterday's data? My DB is in UTC+7.00 standard. I need to display it in local standard so that I did a conversion in select statement. And how do I display only yesterday's data?
I'm stuck. Please help me
To get all data from yesterday you should use
SELECT TO_CHAR(IN_DATE + INTERVAL '12' HOUR, 'DD-MON-YYYY HH24:MI:SS')
FROM MY_TABLE
WHERE INCOMING_DATE BETWEEN TRUNC(SYSDATE) - INTERVAL '1' DAY
AND TRUNC(SYSDATE) - INTERVAL '1' SECOND
If, for example, SYSDATE is 05-NOV-2017 18:56:35, the time interval used in the BETWEEN comparison will be from 04-NOV-2017 00:00:00 to 04-NOV-2017 23:59:59. BETWEEN comparisons are inclusive of both endpoints so this will only return data with an INCOMING_DATE of sometime on 04-NOV-2017, in this example.
Best of luck.
only to get the
yesterday's data
make your
WHERE condition as
incoming_date between trunc(sysdate) - interval '1' day and trunc(sysdate) - interval '1' second
My DB is in UTC+7.00 standard. I need to display it in local standard so that I did a conversion in select statement.
Using a magic value (INTERVAL '12' HOUR) does not describe what it means or the assumptions you made when chosing that value. Instead you can better describe the process by using FROM_TS( timestampvalue, timezonestring ) to convert the value from a TIMESTAMP to a TIMESTAMP WITH TIME ZONE data type and then use AT LOCAL TIME to convert it to the local time. Then if you have daylight savings time or port the query to another international location then it will still display in the current local time. Like this:
SELECT TO_CHAR(
FROM_TZ( CAST( in_date AS TIMESTAMP ), '+07:00' ) AT LOCAL TIME,
'DD-MON-YYYY HH24:MI:SS'
)
FROM my_table
WHERE incoming_date >= TRUNC( SYSDATE ) - INTERVAL '1' DAY
AND incoming_date < TRUNC( SYSDATE )
And how do I display only yesterday's data?
TRUNC( SYSDATE ) will truncate today's date back to midnight. To get yesterday's data then you can get values that are greater or equal to TRUNC( SYSDATE ) - INTERVAL '1' DAY (one day before midnight today) and also less than TRUNC( SYSDATE ) (midnight today).
I'm not exactly sure I get your question, but I think I can explain some stuff.
I'll be assuming your table is a bit like this:
date_added | some_data | some_more_data
------------|-----------|----------------
date | data1 | data2
As I understand your goal is to fetch all the rows that were added to a table the day before the query is run using a select statement. but your current attempt fails at doing so by also returning today's results.
Here is what's happening (I think):
SYSDATE doesn't just give you the current date, it also gives you the time. You can see that for your self by simply altering your current session and setting the date/time format to one that includes both time and date
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';
The reason why you would be getting today's rows is simple, your query is asking for all the rows who's date_added field is between right now and right now - 24 hours. Not today and today - 24 hours.
So what is the solution?
Use the TRUNC function to trim the SYSDATE to the day instead!
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions201.htm
SELECT
T.*
FROM
MY_TABLE T
WHERE
T.DATE_ADDED BETWEEN (TRUNC(SYSDATE,'day') - 1) AND TRUNC(SYSDATE,'day');
As you did mention timezones being a thing keep in mind that SYSDATE returns the date on the server itself and not your computer's.
More on that here: https://stackoverflow.com/a/17925834/7655979
Usually I compare the date only using Trunc.
WHERE trunc(incoming_date) = trunc(sysdate-1)

how to set parameter for date plus days in oracle

i have problem to add set parameter for date plus days in oracle. i have two parameter. that is one for date and one for day. I have tried that way but not successful.
This my query:
SELECT DISTINCT
mhn.id_mohon,
mhn.kod_urusan,
mhn.kod_caw,
nvl(to_char(mhn.trh_masuk, 'DD/MM/YYYY'), '-') trh_mohon,
nvl(to_char(mhn.trh_masuk, 'MM'), '-') bln
FROM mohon mhn
WHERE mhn.trh_masuk = to_date(:p_date1, 'DD/MM/YYYY') + INTERVAL :days DAY;
Can you check what the problem is my parameter?
I expect that you need:
to_date(:p_date1,'DD/MM/YYYY') + :days
or:
to_date(:p_date1,'DD/MM/YYYY') + :days * INTERVAL '1' DAY
An interval literal shows that the interval length has to be a quoted fixed value; it cannot be a variable.
You can use the numtodsinterval() function instead:
mhn.trh_masuk = to_date(:p_date1,'DD/MM/YYYY') + numtodsinterval(:days, 'DAY')
Or you could just add the number of days to the date:
mhn.trh_masuk = to_date(:p_date1,'DD/MM/YYYY') + :days