I create query which display all item which is cancel in period
start.date - end.date
select substr(tarifa,1,2) as tarifa, count(*) as komada
from pol p, uvod u, doppov d
WHERE (datum_dop >='1-jan-07') AND (datum_dop<='1-jul-13')
and izdavanje>='01-jul-10'
and p.orgjed = u.sorgz (+)
and p.polica=d.polica and d.pov_dopl='P'
--and DATUM_PREKIDA is not null
and d.status='F'
and cisti_ao(p.polica)!=0
group by substr(tarifa,1,2)
Now I want to edit this query column izdavanje. If user enter '27-sep-xx year' it need to display item in period start-date '01-jan-xx' until '27-sep-xx year'
So start date need to be always '1-jan-xx year' and end date need to be entered date like '19-aug-xx'.
Any idea how to fix this problem ?
This:
and izdavanje>='01-jul-10'
will become
and izdavanje between to_date('01.01.' || substr(:BLOK.IZDAVANJE, -2), 'dd.mm.rr')
and to_date(:BLOK.IZDAVANJE, 'dd-mon-rr')
substr will return xx year
to_date will convert the whole value into a valid date
Now, as it is Forms, you might need to adjust it a little bit (depending on column datatype as well as form item's datatype), but - that's the general idea.
You want to use TRUNC( date_value, 'YY' ) to truncate it to the start of the year:
AND izdavanje BETWEEN TRUNC( '01-jul-10', 'YY' ) AND '01-jul-10'
However, you should also note that '01-jul-10' is a text literal so, when a date is required, Oracle has to perform an implicit conversion from the text literal to a date. You would be better performing an explicit conversion (as Oracle's default format is the NLS_DATE_FORMAT session parameter and ANY user can change this value in their own session and changing that will break your query without any modification of your code).
For example, to perform an explicit cast to a date:
AND izdavanje BETWEEN TRUNC(
TO_DATE( '01-jul-10', 'DD-MON-RR', 'NLS_DATE_LANGUAGE = American' ),
'YY'
)
AND TO_DATE( '01-jul-10', 'DD-MON-RR', 'NLS_DATE_LANGUAGE = American' )
Also, if your izdavanje date values have time components then '01-jul-10' will be converted to a date at midnight (00:00:00) so you will not get any values returned for that day that have time components between 2010-07-01 00:00:01 and 2010-07-01 23:59:59. If this is relevant and you want those values returned then you should use:
AND izdavanje >= TRUNC(
TO_DATE( '01-jul-10', 'DD-MON-RR', 'NLS_DATE_LANGUAGE = American' ),
'YY'
)
AND izdavanje < TO_DATE( '01-jul-10', 'DD-MON-RR', 'NLS_DATE_LANGUAGE = American' )
+ INTERVAL '1' DAY
You can modify a date inside a query using TO_CHAR() function:
Instead of:
and izdavanje>='01-jul-10'
use this:
and izdavanje between TO_CHAR( :BLOK.IZDAVANJE, 'YYYY-01-01' )
and TO_CHAR( :BLOK.IZDAVANJE, 'YYYY-MM-DD 23:59:59' )
TO_CHAR( :BLOK.IZDAVANJE, 'YYYY-01-01' ) takes only the year from the date and adds '-01-01' (January 1st) to it.
TO_CHAR( :BLOK.IZDAVANJE, 'YYYY-MM-DD 23:59:59' ) adds the max time of the day to the date because 'between xxx and yyy' means equal or less than 00:00:00 of day yyy and all timestamps with a timestamp greater than 00:00:00 but the same day won't be covered when using time values in :BLOK.IZDAVANJE.
Related
how to get previous month or last two month data in oracle.
My date format is YYYY,MM,DD.
from google search i got those solution,
select * from IM_LAPTOP
where ADD_DATE >= add_months(sysdate, -12);
select *
from IM_LAPTOP
where ADD_DATE between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1));
But its showing not a valid month
My date format is YYYY,MM,DD
Unless you are using a string to store dates then, no, it is not; a DATE is a binary data type (consisting of 1-byte for each of: century, year-of-century, month, day, hour, minute and second and it always has those components) and it has no format.
how to get previous month or last two month data in oracle
To get the data from 2 months before this instant in time (i.e. if it is now 2021-04-05 16:39:24 and you want it from 2021-02-05 16:39:24, two months prior) then:
SELECT *
FROM your_table
WHERE date_column >= ADD_MONTHS( SYSDATE, -2 )
To get the data starting from midnight on the 1st day of last month:
SELECT *
FROM your_table
WHERE date_column >= ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), -1 )
If you only want the data from the preceding month then:
SELECT *
FROM your_table
WHERE date_column >= ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), -1 )
AND date_column < TRUNC( SYSDATE, 'MM' )
If your "date" is actually a VARCHAR2 column with the format YYYY,MM,DD then you should change it to a DATE column but if for some reason you cannot then at least the characters are in order of highest-to-least significance and you can perform an alphanumeric comparison and just wrap the right-hand side of the filters in TO_CHAR:
SELECT *
FROM your_table
WHERE date_column >= TO_CHAR( ADD_MONTHS( SYSDATE, -2 ), 'YYYY,MM,DD' )
I have a table with some columns of Date datatype. I need to keep the Date part as it is, but I need to format the time part to 00:00:00 for all of them.
For example:
09-FEB-14 09:00:00
10-MAR-12 12:00:00
I need to update them to:
09-FEB-14 00:00:00
10-MAR-12 00:00:00
How can I do this?
Since you appear to want to truncate the time part back to midnight then you can just use the TRUNC function:
UPDATE your_table
SET date_column = TRUNC( date_column )
If, instead, you want to set them to a specific time then you can use TRUNC and add an INTERVAL literal:
UPDATE your_table
SET date_column = TRUNC( date_column ) + INTERVAL '12:34:56' HOUR TO SECOND;
If you want to take an hour off the time then you can subtract an INTERVAL literal:
UPDATE your_table
SET date_column = date_column - INTERVAL '1' HOUR;
or subtract a fraction of a day:
UPDATE your_table
SET date_column = date_column - 1/24;
When I ran a query to get date it is retrieved in this format 'yyyy/mm/dd hh:mm:ss.SSS' but I need to convert it to mm/dd/yyyy.
I'm using this query for conversion
select
to_char(
add_months (
to_date(
to_char(
trunc(
TO_DATE('2016/01/01 00:00:00.0', 'YYYY/MM/DD HH24:MI:SS.SSS')
), 'MM/DD/YYYY' -- to char
),'MM/DD/YYYY' -- to date
), -2*1 -- add months
), 'MM/DD/YYYY' -- to char
) START_DATE,
to_char(
add_months (
to_date(
to_char(
trunc(
TO_DATE('2017/01/01 00:00:00.0', 'YYYY/MM/DD HH24:MI:SS.SSS')
), 'MM/DD/YYYY' -- to char
), 'MM/DD/YYYY' -- to date
), 3 -- add months
), 'MM/DD/YYYY' -- to char
) END_DATE
from dual;
Output is
ORA-01810: format code appears twice
01810. 00000 - "format code appears twice"
The problem is in the conversion of to_date itself. The below conversion itself is throwing the error you mentioned
select
TO_DATE('2017/01/01 00:00:00.0', 'YYYY/MM/DD HH24:MI:SS.SSS') END_DATE
from dual;
You need to use it like below if you want to convert the string with timestamp to timestamp
select TO_TIMESTAMP('2017/01/01 00:00:00.0', 'YYYY/MM/DD HH24:MI:SS.FF') from dual
This will simply satisfy your need rather than making so many conversions.
select to_char(
add_months(
TO_TIMESTAMP('2017/01/01 00:00:00.0', 'YYYY/MM/DDHH24:MI:SS.FF'),
-2),
'mm/dd/yyyy') from dual
ORA-01810: format code appears twice
That's because of SS.SSS. SSS is not a valid date format. You are trying to handle fractional seconds but:
the correct format mask for that is FF
DATE doesn't support fractional seconds, only TIMESTAMP
Really date format is a display issue and should be handled by the client's NLS settings. But if you really must do it in SQL this is all you need:
select
to_char(DATE '2015-11-01', 'MM/DD/YYYY') START_DATE
, to_char(DATE '2017-04-01', 'MM/DD/YYYY') END_DATE
from dual;
You don't need trunc() because the date literals are already set to midnight. You don't need add_months() because you can just change the value of the date literal. You don't need to cast the date to a string back to a date because you just don't.
When I run following query I got error.Can Someone help me to solve this.
select trunc('27-oct-97','dd-mm-yy') form dual;
when I run this query i got following error:
Error:inline number function.
The TRUNC function has the signature:
TRUNC( date_value, format )
You are providing a string value instead of a date value and 'dd-mm-yy' is an invalid format (you just want to truncate to the start of the day using 'dd' as the format or the start of the month using 'mm' or the start of the year using 'yy' - but using all three together does not make sense).
You can use ANSI date literals to specify the date:
SELECT TRUNC(
DATE '1997-10-27',
'DD'
)
FROM DUAL
Or use the TO_DATE function:
SELECT TRUNC(
TO_DATE( '27-oct-97', 'DD-MON-RR' ),
'DD'
)
FROM DUAL
(and you can also omit the 'DD' format argument as the default is to truncate to the start of the day.)
But, in both cases, the truncation is redundant as the date's time component is already midnight so does not need truncating.
What you want is a date value that has a non-midnight time component:
SELECT TRUNC(
TO_DATE( '1997-10-27 12:34:56', 'YYYY-MM-DD HH24:MI:SS' ),
'DD'
)
FROM DUAL
or to truncate to the start of the month or year:
SELECT TRUNC(
DATE '1997-10-27',
'MM'
)
FROM DUAL
You have two options:
1) Remove the time portion from the date truncate into the nearest date:
TRUNC(DATE)
2) Use format, to specify which values to trunc:
TRUNC(DATE,year)
Truncates (will turn to 1) everything that is before the format , in this example the year.
So this:
trunc(to_date('27-oct-97','dd-mm-yy'),'YEAR')
Will output this:
01-jan-97
I am trying to figure out how to create an SQL query that will check for (:FROM_DATE) and (:TO_DATE) parameters and if NULL to put the past month dates in for the two values, and if not NULL to accept whatever values are entered in the parameters.
For example:
if the user enters (01-JAN-17) as FROM_DATE, and (31-JAN-17) as TO_DATE, I want the query to not automatically pass any values for the TO_DATE and FROM_DATE.
if the user does not enter any values for TO_DATE and FROM_DATE or there are NULL values passed in, I want the query to automatically enter the the past months values (i.e., if query is run July 1st 2017, the FROM_DATE would be 01-JUN-17 and the TO_DATE would be 30-JUN-17).
I was hinted to use a coalesce statement to handle multiple values and NULLS (i.e., AND ( (coalesce(null, :P_ORG) is null) or (ORG.ORGANIZATION_ID in :P_ORG)))???
Any help would be greatly appreciated.
Something like:
SELECT *
FROM your_table
WHERE your_date_column BETWEEN TO_DATE( :from_date, 'DD-MON-YYYY' )
AND TO_DATE( :to_date, 'DD-MON-YYYY' )
OR ( ( :from_date IS NULL OR :to_date IS NULL )
AND your_date_column BETWEEN ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), -1 )
AND TRUNC( SYSDATE, 'MM' ) - 1
);
If either (or both) :from_date or :to_date is NULL then the dates will be compared to the previous month.
If your table has dates where the time component is not always set to midnight then you will need to use:
SELECT *
FROM your_table
WHERE your_date_column BETWEEN TO_DATE( :from_date, 'DD-MON-YYYY' )
AND TO_DATE( :to_date, 'DD-MON-YYYY' )
OR ( ( :from_date IS NULL OR :to_date IS NULL )
AND your_date_column >= ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), -1 )
AND your_date_column < TRUNC( SYSDATE, 'MM' )
);
Proof of concept: consider the following query, where we have dates and values, and we want to sum the values for the dates that fall between :from_date and :to_date. If either of them is null, the query will use the first day of the prior month for from_date and the last day of the prior month for to_date. Note that this will cause problems if one date is given an actual value and the other is left null - you didn't explain how you would want that handled. But that's a different issue.
I use SQL developer, and in it I don't know how to pass in dates; I show passing in strings, and converting them to dates.
with
test_data ( dt, val ) as (
select date '2017-05-29', 200 from dual union all
select date '2017-06-13', 150 from dual union all
select date '2017-06-18', 500 from dual
)
select sum(val) as sum_val
from test_data
where dt between coalesce(to_date(:from_date, 'yyyy-mm-dd'),
add_months(trunc(sysdate, 'mm'), -1))
and coalesce(to_date(:to_date , 'yyyy-mm-dd'), trunc(sysdate, 'mm') - 1)
;
Yes, you can use COALESCE (or Oracle's NVL). When a parameter is null, replace it with the default date.
select *
from mytable
where mydate >= coalesce(:from_date, trunc(sysdate - interval '1' month), 'month')
and mydate <= coalesce(:to_date, last_day(sysdate - interval '1' month));