split int col in Teradata - teradata

I was trying to split int column in Teradata but its showing error
*** Failure 9134 Unsupported type detected.
SELECT col1,strtok(col2,0 ,1) FROM table;

Related

Manipulating timestamps without converting them to datetime in MySql 8

It seems MySql 8 differenciates TIMESTAMP from DATETIME more than previous versions (at least more than 5.7) and java drivers understand a Timestamp is universal (senconds since epoch) while DATETIME is like a textual representation of date and time without timezone information, it is not an instant in time.
I need to work with timestamps but I need to add 1 second to one of them in a SELECT query. Unfortunately I can't do it. If I try to do it then it gets converted to DATETIME with it's side effects, as they are not the same.
This code can be using for testing without other programming language:
CREATE TABLE z (
`id` bigint unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
`myTs` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB;
insert into z (myTs) values (TIMESTAMP'2023-01-01 00:00:00+00:00');
create table x as select myTs + interval 1 second from z limit 1;
desc x;
drop table x;
drop table z;
You will get myTs + interval 1 second | datetime | ...
But if you remove + interval 1 second then you get myTs | timestamp | ...
I have read the documentation and tried different functions and I couldn't avoid or reverse this conversion.
Specifically I tried at least timestamp(myTs + interval 1 second), timestampadd(second, 1, myTs), date_add(myTs, interval 1 second) and timestamp(myTs + 1).
I need to either sum 1 second to a timestamp without it being converted to datetime or a way to convert a datetime to a timestamp type (providing a time zone if needed) in MySql 8.
I'm using MySql 8.0.30.
Thank you.

How to cast a column into decimal of varying significant digits in Oracle

I have a column that is stored in ###0.0000000000 format. In a report I'm generating I need it to only show a few significant digits. Problem is the number needed changes based on the product with a default of 2. There's a column in another table that provides the required digits per each product.
I've tried a few things so far but it seems to not like it and throws a syntax error.
Cast(A.Price as Numeric(10,coalesce(B.Sig_Digits,2)))
That threw an error so I tried making the coalesce part a column and aliasing it in case the coalesce broke it, and that didn't work either. Round will take a column as an argument but I don't want it to round. Other than an ugly
case when Sig_digits = 1 then to_char(price,'###0.0') when Sig_digits = 2...
etc. what other options are there? This is a very large report, with 100+ columns and a few million rows so I'd prefer to not do the case when.
Use TO_CHAR with RPAD to add 0s to the end of the format model to the correct number of decimal places:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE table_name ( value, sig ) AS
SELECT 123.456789, 2 FROM DUAL UNION ALL
SELECT 123456789.123456789, 7 FROM DUAL;
Query 1:
SELECT TO_CHAR( value, RPAD( 'FM999999999990.', sig + 15, '0' ) )
FROM table_name
Results:
| TO_CHAR(VALUE,RPAD('FM999999999990.',SIG+15,'0')) |
|---------------------------------------------------|
| 123.46 |
| 123456789.1234568 |

Split column value in sqlite

Am new to sqlite in my learning I come across the subString function so in my exercise, My table name is t1 and my column value is Partha000099 I want to increment by 1 eg., Partha000100 when i try with
SELECT SUBSTR(MAX(ID),6) FROM t1
am getting output as 000099 when I increment by 1 with the below query
SELECT SUBSTR(MAX(ID),6)+1 FROM t1
am getting output as 100, Now my question is how to construct it back as I expect
I tried with the below query,
SELECT 'Partha' || SUBSTR(MAX(ID),6)+1 FROM t1
am getting output as 1. Please some one help me.
While my solution will work, I would advice you against this type of key generation. "SELECT MAX(ID)+1" to generate the next key will be fraught with problems in more concurrent databases and you risk generating duplicate keys in a busy application/system.
It would be better to split the key into two columns, one with the group or name 'Partha', and the other column with an automatically incremented number.
However, having said that, here's how to generate the next key like your example.
You need to:
Split the key into two
Increment the numeric part
Convert it back to a string
Pad it to 6 digits
Here's the SQL that will do that:
SELECT SUBSTR(ID, 1, 6) || SUBSTR('000000' || (SUBSTR(MAX(ID), 7)+1), -6) FROM t1;
To pad it to 6 digits, I prepend 6 zeroes, then grab the last 6 digits from the resulting string with this type of expression
SUBSTR(x, -6)
The reason why you got 1 was that your expression was grouped like this:
SELECT .... + 1
And the .... part, your string concatenation, was then attempted converted to a number, which resulted in 0, thus 0+1 gives 1.
To get the unpadded result you could've just added some parenthesis:
SELECT 'Partha' || (SUBSTR(MAX(ID),6)+1) FROM t1
^ ^
This, however, would also be wrong as it would return Partha1, and that is because SUBSTR(..., 6) grabs the 6th character and onwards and the 6th character is the final a in Partha, so to get Partha100 you would need this:
SELECT 'Partha' || (SUBSTR(MAX(ID),7)+1) FROM t1
^

Why is this SQL returning "Invalid Number" when I convert VARCHAR2 to an INTEGER?

I have this SQL:
SELECT C1,CAST(C1 as NUMBER) FROM my_materialized_view WHERE C1 IS NOT NULL AND C1 != '0'
C1 is a VARCHAR2 column that contains nulls and 0 values. Those are filtered out in the WHERE clause. This query works if I SELECT C1 FROM - remove the CAST() - from the statement.
When I run the above SQL in its entirety, I get ORA-01722: invalid number.
How should I convert a column in the materialized view to a number so I can perform calculations?
UPDATE - I also tried select cast(c1 as integer) as suggested in comments. It returns the same error.
UPDATE - I ran this select C1 from my_materialized_view where C1 IS NOT NULL and C1 != '0' order by C1 and did not find any values outside the range of 1001000 to 999300. Seems like a valid test.
This means that some values in C1 column are not numeric strings. You cannot cast a string like '1 0' (with space in between) into number for example.
Try using SELECT C1 WHERE ISNUMERIC(C1) = 0 to determine where the problematic value is.
For Oracle:
http://odiexperts.com/is_number-at-oracle-a-work-around/

Date Function in Teradata

Is there a function in Teradata, that "makes" a date by giving day, month any year as parameters?
SO if I have integer parameters p1_day, p2_month, and p3_year (which are, by the way, attributes), is there a function like
date_function (p1_day, p2_month, and p3_year) -> for example '2013-12-11'
In TD13.10+ you can create a simple SQL UDF:
-- (year, month, day) to date, "invalid date" error if no valid date
REPLACE FUNCTION ymd_to_date(y INTEGER, m INTEGER, d INTEGER)
RETURNS DATE
SPECIFIC ymd_to_date
RETURNS NULL ON NULL INPUT
CONTAINS SQL
DETERMINISTIC
COLLATION INVOKER
INLINE TYPE 1
RETURN
((y - 1900) * 10000 + (m * 100) + d (DATE))
Dieter
One example in teradata:
BTEQ -- Enter your SQL request or BTEQ command:
sel cast ('11'||'-'||'12'||'-'||'12' as date format 'dd-mm-yy');
sel cast ('11'||'-'||'12'||'-'||'12' as date format 'dd-mm-yy');
*** Query completed. One row found. One column returned.
*** Total elapsed time was 1 second.
(((('11'||'-')||'12')||'-')||'12')
----------------------------------
11-12-12
So you can simply achieve your desired result by following query:
sel cast (cast(p1_day as char(2))||'-'||cast(p2_month as char(2))||'-'||
cast(p3_year as char(2)) as date format 'dd-mm-yy');
P.S. : There doesn't seem any such built-in function in teradata.
As far i as i know there is no predefined date function where you pass the integers and it returns the date.. however you can write you know UDF..
To add to Deiter's function, look at the below queries. Teradata stores dates as Integers with an offset from 1900.
SELECT CAST(CURRENT_DATE AS INTEGER);
---- 1150818
SELECT CURRENT_DATE;
--- 2015-08-18
---- the format of storage is (<year> - 1900)mmdd
SELECT (2015 -1900)*100000 + (8 * 100)+ 18;
------ 1150818
115 years from 1900, month followed by date.

Resources