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

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!!

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 a date value stored in another table and increment it by x days?

I'm using a PostgreSQL database and have one table "event_date" with "started_at" (DATE format, e.g. '2019-10-29') values which are also the PRIMARY KEY in this table.
Now I want to insert this "started_at" value in another table "event_days" but increasing the date by x days.
Can someone explain how to achieve this? Thanks a lot!
Use an INSERT with a SELECT:
insert into other_table (started_at, location, moderator)
select started_at + 42, 'Hall 5', 'Tom'
from event_days;
+ 42 add 42 days to the date value.
if you really need insert the related record you could use a insert select
insert into event_days(started_at, location , moderator)
select started_at + interval '10 day', 'hall 5' , 'Tom'
from event_date

how to check Date is between 2 dates in 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

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