Max date between two dates teradata - sqlite

I am running the following proc sql to pull out the max date.
Proc sql;
Connect to TERADATA (login details);
Create table dates as
Select * from connection to TERADATA
( select max (date1,'2011-12-31') from table1
);
Quit;
Error:
Syntax error: expected something between the word 'date1' and ','
Can someone help me where I am doing wrong?

In most flavors of SQL, the max function is an aggregation function, which only takes one argument and then takes the column (or whatever is passed to it) and chooses the maximum value from that column.
SAS is different in that it overloads max to also work as a row-level function.
To do this you could do:
Proc sql;
Connect to TERADATA (login details);
Create table dates as
Select max(date1,'2011-12-31') from connection to TERADATA
( select date1 from table1
);
Quit;
Which pulls it out of the teradata and into SAS where it's legal to do that.

You can do this in-database (push down optimization) with Teradata if you use the GREATEST function and cast the dates to INTEGER:
Proc sql;
Connect to TERADATA (login details);
Create table dates as
Select * from connection to TERADATA
( select GREATEST (CAST(date1 AS INTEGER), CAST(CAST('2011-12-31' AS DATE) AS INTEGER)) from table1
);
Quit;
Note: I double casted the second parameter to be on the safe side, even though it is being passed to Teradata in an implicit ANSI date format. If your date is nullable in the table (date1), there may be some obstacles with COALESCE.

Related

Inserting SAS datetime into Teradata using proc sql

I have a SAS datetime stored in a macro variable and try to write that into a timestamp column in teradata using proc sql. E.g. I can write that into a string column with %BQUOTE('&macrovariable') and it returns 14APR2020:06:47:20. But I am failing to convert that into a timestamp and write into timestamp field in teradata. Cast as timestamp did also not work :( It returns ERROR: Teradata execute: Invalid timestamp.
My Code:
INSERT INTO MYTABLEWITHDATETIMEFIELD
VALUES (
%BQUOTE('&macrovariable')
)
Could you help me out? THANKS!
Best regards
Flo

Force Oracle's sysdate to return different value for multiple statements

I'd like to force Oracle sysdate function to return different values for separate statements, just like it does in Postgres. I've done some digging over the documentation, net and SO itself but couldn't find an answer to address this.
Documentation seems to be pretty poor for this one: see for yourself
I'm using Oracle 11g with SQL Developer 18.3
Please read on the MVCE below.
After executing this:
create table t(a timestamp);
insert into t values (sysdate);
insert into t values (sysdate);
insert into t values (sysdate);
select * from t;
I get:
A
---------------------------
18/12/25 04:25:59,000000000
18/12/25 04:25:59,000000000
18/12/25 04:25:59,000000000
I would want to get (changed by hand):
A
---------------------------
18/12/25 04:25:59,1234
18/12/25 04:25:59,7281
18/12/25 04:26:00,1928
Real issue is presented within different CALL statements to procedures, but the above sample seems to replicate the issue for me.
UPDATE
One thing I found to be helpful is to put pauses between statements, but this really isn't what I'm looking for:
set pause on;
create table t(a timestamp);
insert into t values (sysdate);
pause
insert into t values (sysdate);
pause
insert into t values (sysdate);
As noted in the documentation, the sysdate function returns a date, which only has precision down to seconds - it does not support fractional seconds. So, multiple calls within the same second will always get the same value, and you can't force it to do anything else.
You're putting that date value into a timestamp column, which is causes an implicit conversion from one data type to the other, but that conversion can't set/create a new fractional seconds value - it keeps the implicit fractional seconds from the date, which is of course always zero.
As well as sysdate, Oracle has a systimestamp function, which returns a timestamp with time zone value - and that does have fractional seconds. The precision is limited by the platform you're running on. If you use that to populate your plain timestamp column then an implicit conversion still occurs, but you essentially just throw away the time zone information.
Oracle also supports current_date and current_timestamp, which are very similar - except they return the date/time in the current session time zone, rather than in the server time zone as the sys* versions do.
I found that current_timestamp does the job:
drop table t;
create table t(a timestamp);
insert into t values (current_timestamp);
insert into t values (current_timestamp);
insert into t values (current_timestamp);
select * from t;
Outputs:
A
---------------------------
18/12/25 04:48:54,134000000
18/12/25 04:48:54,142000000
18/12/25 04:48:54,149000000

How to Implement Timestamp in oracle?

create table abc_test(
id number,
rv timestamp
);
insert into abc_test(id,rv) values (1, CURRENT_TIMESTAMP);
Is there any better way to do it?
Can the timestamp be stored in the database in some binary format like "01x0000000000046565".
In Microsoft sql, this can easily be done as below :
create table xyz_test(id1 timestamp, name varchar(50))
insert into xyz_test (Name) values('person1')
select * from xyz_test
The above query will show some binary form for the timestamp column and "person1" in the name column
How to get the same result in the oracle?
It is indeed stored in a binary format -- the tool that you are using translates it when it is retrieved.
Display of dates and timestamps is dependent on tool configuration, and on session settings etc.. You can read the timestamp in whatever format you like -- consult the documentation for To_Char(datetime).

Insert multiple rows into SQL Server based on start and end dates

I need to insert several rows into a SQL Server database based on Start Date and End Date textboxes.
E.G. tbStartDate.Text = "25/12/2012" and tbEndDate.Text = "29/12/2012" therefore I need to insert individual rows for the following dates:
25/12/2012
26/12/2012
27/12/2012
28/12/2012
29/12/2012
Please can you help me with the necessary T-SQL to achieve this?
As always there are a few ways. Here are some of them:
You can write code in your app that loops through the days and inserts a single record per day. (generally the worst design)
You can call some SQL script to do it all in the database.
You can wrap up your SQL script in a stored procedure and pass in the start and end date and get the stored procedure to do it for you.
You can cross join to a pre existing tally table and use it to generate your records.
If you can provide
-the version of SQL Server that you're using
-what the table looks like
-whether you're using C# or VB
then we can help further as it can be difficult to pass dates into databases. It can be particularly difficult if you do not validate them.
Anyway here is option 3 for you.
CREATE PROC dbo.t_test
#StartDate DATETIME,
#EndDate DATETIME
AS
WHILE #StartDate <= #EndDate
BEGIN
INSERT INTO YourTable(YourDateField) VALUES (#StartDate)
SET #StartDate = DATEADD(d,1,#StartDate)
END
Then you need to call this stored procedure (called dbo.t_test) from ASP.Net and pass in your two date parametes as dates.
Declare #Startdate datetime
Select #Startdate='20121025'
While #Startdate<='20121029'
begin
if not exists(select * from dummy where DATE=#Startdate)
insert into dummy (date) values (#Startdate)
set #Startdate=#Startdate + 1
end;

teradata : select data into variable

in oracle we have
decalre
v_data number ;
begin
select max(deptno) into v_data from dept;
end;
do we have this type of advatntage of in terdata like selecting the data from table into a variable
can u give the equivalent code in terdata
Thanks
In teradata you can use variables only in stored procedure, you cannot use the variables in Teradata SQl statements which are outside of the stored procedure.
You can load the max value into a temporary table and can access it for your manipulations

Resources