how to check Date is between 2 dates in SQL? - sql

i want retrieve rows based on Date that within 2 dates or
it will be greater than date or less than date
where id =5
AND ( :fromDate is null or trunc ( :fromDate ) >= trun(TABLE.DEPOSIT_DATE ))
AND ( :toDate is null or trunc ( :toDate )<= trunc (TABLE.DEPOSIT_DATE ))
when i pass paramters to :fromDate and :ToDate at this format (7/25/2018 1:21:55 PM) for example
the query return 0 rows

Try using "BETWEEN" operator as below example
SELECT * FROM employee where joining_date BETWEEN '2006-02-14 04:34:33' AND '2016-02-15 04:34:12';

If you are using sql server
then first set the date format
like : - set daqteformat dmy
and date condition u can use between
like : Entrydate between '01/01/2018' and '31/01/2018'

Why you cannot use between ? check below example using plsql block statement to use bind variable the same as your example
SET serveroutput ON size 2000
/
declare
T_DATE date;
F_DATE DATE;
C_ID number(2);
begin
T_DATE := to_date('01/07/2018','dd/mm/yyyy');
F_DATE := to_date('01/06/2018','dd/mm/yyyy');
delete from ex_employee;
insert into ex_employee (id, X_NAME, T_ADDED) values (1, 'aa', sysdate);
insert into ex_employee
(id, X_NAME, T_ADDED)
values
(2, 'bb', sysdate - 1);
insert into ex_employee
(id, X_NAME, T_ADDED)
values
(3, 'cc', to_date('20/06/2018','dd/mm/yyyy'));
commit;
select id
into C_ID
from ex_employee
where T_ADDED between F_DATE and T_DATE or F_DATE is null or T_DATE is null;
dbms_output.put_line(c_id);
end;
/
PL/SQL procedure successfully completed
3

Related

Oracle date data type problem - I get wrong format as result in table

I need to set a column with date data type TO_TIMESTAMP to correct format to insert some data with merge into declaration.
The table.column = settings.data
The insert value as example: '28.01.2022 14:07'
But column is set as TIMESTAMP(6) format.
So need this to insert as: '28.01.2022 14:07:00,000000'
DECLARE
PROCEDURE settings_import
(
in_id IN NUMBER
in_data IN TIMESTAMP
)
IS
BEGIN
MERGE INTO settings a
using (select in_id AS ID, in_data AS data from dual) b
on (a.ID = b.ID)
when not matched
then
INSERT into settings (ID, data) values (ID, data)
when matched
update set a.data = b.data
END settings_import;
BEGIN
settings_import (12, '28.01.2022 14:07');
END;
/
When I try this I get in column data this entry, but it's wrong: 28.01.2020 22:14:07,000000
right should be: '28.01.2022 14:07:00,000000'
When I try in the values (b.ID, TO_TIMESTAMP(b.data, 'DD.MM.YYYY HH24:MI:SS.FF')
I get this error: ORA-01830: date format picture ends before converting entire input string
How can I fix this? thank you!
Your code has many, many syntax errors (missing commas, missing semi-colons, missing keywords, extra keywords)... If you fix those then:
'28.01.2022 14:07' is not a TIMESTAMP data type it is a string literal.
Either use a TIMESTAMP literal:
DECLARE
PROCEDURE settings_import(
in_id IN SETTINGS.ID%TYPE,
in_data IN SETTINGS.DATA%TYPE
)
IS
BEGIN
MERGE INTO settings a
USING DUAL
ON (a.ID = in_id)
WHEN NOT MATCHED THEN
INSERT (ID, data) values (in_ID, in_data)
WHEN MATCHED THEN
UPDATE SET a.data = in_data;
END settings_import;
BEGIN
settings_import (
12,
TIMESTAMP '2022-01-28 14:07:00'
);
END;
/
Or explicitly use TO_TIMESTAMP:
DECLARE
PROCEDURE settings_import(
in_id IN SETTINGS.ID%TYPE,
in_data IN SETTINGS.DATA%TYPE
)
IS
BEGIN
MERGE INTO settings a
USING DUAL
ON (a.ID = in_id)
WHEN NOT MATCHED THEN
INSERT (ID, data) values (in_ID, in_data)
WHEN MATCHED THEN
UPDATE SET a.data = in_data;
END settings_import;
BEGIN
settings_import (
12,
TO_TIMESTAMP('28.01.2022 14:07', 'DD.MM.YYYY HH24:MI')
);
END;
/
Which, if you have the table:
CREATE TABLE settings (id NUMBER, data TIMESTAMP);
Both will give a table with the value (with the NLS_TIMESTAMP_FORMAT of YYYY-MM-DD HH24:MI:SS.FF):
ID
DATA
12
2022-01-28 14:07:00.000000
db<>fiddle here
I've had some syntax error as I wanted to simplify my code for better understanding, sorry, see below the corrected code which now works.
Thanks pmdba & MT0!
DECLARE
PROCEDURE settings_import
(
in_id IN NUMBER,
in_data IN varchar2
)
IS
BEGIN
MERGE INTO settings a
using (select in_id AS ID, in_data AS data from dual) b
on (a.ID = b.ID)
when not matched
then
INSERT (ID, data) values (b.id, to_timestamp(b.data, 'DD/MM/YYYY HH24:MI:SS.FF'))
when matched
then
update set a.data = to_timestamp(b.data, 'DD/MM/YYYY HH24:MI:SS.FF');
END settings_import;
BEGIN
settings_import (12, '11/11/2022 14:07');
END;
/

PostgreSQL temp function for minimum date

I am trying to create a temp function to avoid duplicating blocks of code in the script. I think by creating a temp function in PostgreSQL I will be able to keep the script succinct but I am unfamiliar with functions on PostgreSQL
I would like to get the minimum date value by a specific group,
i.e.
I have the following SQL script
select
my_tale.some_value_id
, min(my_tale.datetime::date)
filter(
where
my_tale.some_value_id_2 in (1, 2)
) as firs_date
from
my_tale
group by
1
I would like to swap out some_value_id_2 in a function so I don't have to reuse code, i.e. I don't want to do this:
select
my_tale.some_value_id
, min(my_tale.datetime::date)
filter(
where
my_tale.some_value_id_2 in (1, 2)
) as firs_date_1
, min(my_tale.datetime::date)
filter(
where
my_tale.some_value_id_2 in (3, 4)
) as firs_date_2
, min(my_tale.datetime::date)
filter(
where
my_tale.some_value_id_2 in (5, 6)
) as firs_date_3
from
my_tale
group by
1
Ideally I would like to have something like this:
select
my_tale.some_value_id
, temp_function(1,2) as firs_date_1
, temp_function(3,4) as firs_date_2
, temp_function(5,6) as firs_date_3
from
my_tale
group by
1
I have tried playing around with the function below, but can't get it to work:
create function pg_temp.get_first_date(id_1 int, id_2 int)
returns date
language sql
as $function$
min(my_tale.datetime::date)
filter(
where my_tale.some_value_id_2 in ($id_1, $id_2)
);
$function$
;
select
my_tale.some_value_id
, pg_temp.get_first_date(1,2) as firs_date_1
from
my_tale
group by
1
Any advice would be appreciated, thanks in advance
sql fiddle
reference: https://dba.stackexchange.com/questions/300507/what-does-begin-atomic-end-mean-in-a-postgresql-sql-function-procedure
begin;
create temp table mytable(mytableid bigint,some_value_id numeric, some_value_id_2 numeric, datetime date);
insert into mytable values (1,1,1,'2022-01-12');
insert into mytable values (1,1,2,'2022-03-01');
insert into mytable values (1,1,3,'2022-01-01');
insert into mytable values (1,1,1,'2022-01-11');
commit;
create function
pg_temp.get_first_date(id_1 int, id_2 int)
returns date
language sql
BEGIN ATOMIC
select min(datetime)
filter(where mytable.some_value_id_2 in ($1, $2)) from mytable;
end;

How to INSERT the continuous Date in HANA with SQL statement?

I have to insert the data like as below from 01-01-2018 to 31-12-2018.
insert into "schema"."tablename" (FISCAL_DATE,FISCAL_DT,REGION_CD,FISCAL_REGION_CD,FISCAL_DATE1,NEW_REGION_CD) values ('2018-01-01', '2018-01-01','EMEA','EUR','01/01/2018', 'EURO');
insert into "schema"."tablename" (FISCAL_DATE,FISCAL_DT,REGION_CD,FISCAL_REGION_CD,FISCAL_DATE1,NEW_REGION_CD) values ('2018-01-01', '2018-01-01','EMEA','EUR','01/01/2018', 'EURO');
insert into "schema"."tablename" (FISCAL_DATE,FISCAL_DT,REGION_CD,FISCAL_REGION_CD,FISCAL_DATE1,NEW_REGION_CD) values ('2018-01-01', '2018-01-01','EMEA','EUR','01/01/2018', 'EURO');
insert into "schema"."tablename" (FISCAL_DATE,FISCAL_DT,REGION_CD,FISCAL_REGION_CD,FISCAL_DATE1,NEW_REGION_CD) values ('2018-01-01', '2018-01-01','EMEA','EUR','01/01/2018', 'EURO');
...
insert into "schema"."tablename" (FISCAL_DATE,FISCAL_DT,REGION_CD,FISCAL_REGION_CD,FISCAL_DATE1,NEW_REGION_CD) values ('2018-12-31', '2018-12-31','EMEA','EUR','12/31/2018', 'EURO');
Is there any alternative SQL statements to achieve this or else need to go with manually update the dates one by one.
Please share your inputs/suggestions.
If I understood you correctly, you want to insert multiple records (day by day) with dates from 2018-01-01 to 2018-12-31.
You can achieve this using WHILE statement.
DO
BEGIN
DECLARE INPUT_DATE date := '2018-01-01';
WHILE INPUT_DATE <= '2018-12-31' DO
INSERT INTO "schema"."tablename" (FISCAL_DATE,FISCAL_DT,REGION_CD,FISCAL_REGION_CD,FISCAL_DATE1,NEW_REGION_CD) values (:INPUT_DATE, :INPUT_DATE,'EMEA','EUR',:INPUT_DATE, 'EURO');
INPUT_DATE = ADD_DAYS(:INPUT_DATE,1);
END WHILE;
END
You can also use a SQL dates table on HANA database and it is very easy to create using SQLScript.
Please check following example (please replace table name and column names according to your model)
do
begin
declare date_start date := '01.01.2018';
declare date_end date := '31.12.2018';
insert into mySampleTransactionData (tdate)
SELECT generated_period_start
FROM SERIES_GENERATE_DATE('INTERVAL 1 DAY', :date_start, add_days(:date_end,1));
end
I have successfully inserted data with the below Query.
insert into "Schema"."tablename" (select to_nvarchar(gen_date, 'YYYY-MM-DD') as fiscal_date,
to_nvarchar(gen_date, 'YYYY-MM-DD') as fiscal_dt,
'AMR' as region_cd,
'AMR' as fiscal_region_cd,
to_nvarchar(gen_date, 'MM/DD/YYYY') as fiscal_date1,
'AMR' as led_region_cd
from (
select generated_period_start as gen_date from SERIES_GENERATE_DATE ('INTERVAL 1 DAY', '2018-01-01', '2018-12-31')
));
Thank You all for your valuable suggestions!!

compare i and i+1 element oracle

I have table
CREATE table table_x
(
id NUMBER, -- ID
NUMBER_history NUMBER, -- consecutive number
start_date date, -- start_date of next id=end_date of previous
end_date date -- should be >=start_date
);
INSERT INTO table_x VALUES (14 , 1, '13-NOV-92' ,'14-NOV-92' );
INSERT INTO table_x VALUES (15 , 2, '14-NOV-92' ,'16-NOV-92' );
INSERT INTO table_x VALUES (19 , 3, '16-NOV-92' ,'18-NOV-92' );
INSERT INTO table_x VALUES (11 , 4, '18-NOV-92' ,'14-NOV-93' );
INSERT INTO table_x VALUES (17 , 5, '15-NOV-93' ,'16-NOV-93' );
INSERT INTO table_x VALUES (151 , 6, '16-NOV-93' ,'17-NOV-93' );
INSERT INTO table_x VALUES (139 , 7, '17-NOV-93' ,'18-NOV-93' );
INSERT INTO table_x VALUES (121 , 8, '19-NOV-93' ,'20-DEC-93' );
INSERT INTO table_x VALUES (822 , 9, '20-DEC-93' ,'20-DEC-93' );
I want write query where I can find where start_date of next row > end_date of previous. they must be equal.
I try to do something like that using NUMBER_history as counter. C-way where I organize cycle by variable i and compare i and i+1 (NUMBER_history and NUMBER_history+1)
select * INTO row_tblx from table_x where NUMBER_history=NUMBER_history and end_date<(select start_date from table_x where NUMBER_history=NUMBER_history+1);
but I must organize loop by n_counter from 1 to last NUMBER_history value and fetch data into multiple row.
How can I do it?
I try
set serveroutput on
DECLARE
CURSOR cur IS
SELECT * FROM table_x;
TYPE row_tblx_type
IS
TABLE OF cur%ROWTYPE;
row_tblx row_tblx_type;
rowx cur%ROWTYPE;
nh_count NUMBER;
BEGIN
FOR NUMBER_history IN cur LOOP
select * INTO row_tblx from table_x where NUMBER_history=NUMBER_history and end_date<(select start_date from table_x where NUMBER_history=NUMBER_history+1);
DBMS_OUTPUT.PUT_LINE (row_tblx(NUMBER_history).id);
END LOOP;
END;
/
How can I do it using for or another loop, multiple records or table of records , cursor, an table row as counter (NUMBER_history)?
How can I do it without cursor?
You don't need PL/SQL or a loop for that:
select *
from (
select id, number_history, start_date, end_date,
lead(start_date) over (order by number_history) as next_start
from table_x
) t
where next_start > end_date;
For example, here's a solution that does not require PL/SQL or LEAD/LAG function
select a.*, b.*
from table_x a
join table_x b
on a.number_history+1 = b.number_history
where b.start_date > a.end_date

Converting date range to multiple period

I have table like below
ID StartDate EndDate
1 15-MAR-2009 8-DEC-2011
2 14-JAN-2010 18-FEB-2013
I need output something like this -
ID StartDate EndDate
1 15-MAR-2009 31-DEC-2009
1 1-JAN-2010 31-DEC-2010
1 1-JAN-2011 8-Dec-2011
2 14-JAN-2010 31-DEC-2010
2 1-JAN-2011 31-DEC-2011
2 1-JAN-2012 31-DEC-2012
2 1-JAN-2013 18-FEB-2013
I have 9i oracle as database, I would perfer to do this with informatica but seems difficult to find solution there, cant create a procedure so need sql query. If anyone can provide in informatica 8.6 then that would be even great.
Edited :-
Create table test_range
(Sr_No number,
start_date date,
end_date date)
create table yr_range
(years date);
Insert statements :-
insert into test_range values (1,'15-MAR-2009','8-DEC-2011');
insert into test_range values (2,'14-JAN-2010','18-FEB-2013');
insert into yr_range values ('31-Dec-2005');
insert into yr_range values ('31-Dec-2006');
insert into yr_range values ('31-Dec-2007');
insert into yr_range values ('31-Dec-2008');
insert into yr_range values ('31-Dec-2009');
insert into yr_range values ('31-Dec-2010');
insert into yr_range values ('31-Dec-2011');
insert into yr_range values ('31-Dec-2012');
insert into yr_range values ('31-Dec-2013');
As suggested in one of the answer, I have created another table to get desired output, is it possible using one table only(i.e. test_range)? I m want exploer all the options before finalizing the one.
If you had something like a years dimension, where each row represented a year, then you would join with it based on whether the year falls within the range. This will give you the number of rows you need, and then for each row you conditionally output the start/end ranges. This should also handle cases where your range is less than a year and thus would not be split up.
y.Year is assumed to be an integer.
See working example here: http://sqlfiddle.com/#!4/d4589/13/11
Create table test_range
(Sr_No number,
StartDate date,
EndDate date);
create table yr_range
(years number);
insert into test_range values (1,'15-MAR-2009','8-DEC-2011');
insert into test_range values (2,'14-JAN-2010','18-FEB-2013');
insert into yr_range values ('2005');
insert into yr_range values ('2006');
insert into yr_range values ('2007');
insert into yr_range values ('2008');
insert into yr_range values ('2009');
insert into yr_range values ('2010');
insert into yr_range values ('2011');
insert into yr_range values ('2012');
insert into yr_range values ('2013');
select
r.Sr_No,
CASE
When to_char( r.StartDate, 'yyyy') = y.years Then r.StartDate
Else to_date( y.years || '/01/01', 'yyyy/mm/dd')
END as StartDate,
CASE
When to_char( r.EndDate , 'yyyy') = y.years Then r.EndDate
Else to_date( y.years || '/12/31', 'yyyy/mm/dd')
END as EndDate
from test_range r, yr_range y
where
to_char( r.StartDate, 'yyyy') <= y.years
AND to_char( r.EndDate, 'yyyy') >= y.years;
You could also generate your years sequence using some of these techniques:
ORACLE SQL:Get all integers between two numbers