Snowflake - Convert varchar to numeric - type-conversion

I have a column(field1) defined as varchar in snowflake. It is storing both string and numbers(ex values: US15876, 1.106336965E9). How can I convert the numeric values to display something like 1106336965, without losing the columns that is storing string values or null values. I am trying try_to_numeric(field1), but this is eliminating the record with string values and showing them as null. Any help is appreciated.

So try_to_number is the way to have numbers, and nulls for non-number without errors. But if you want to keep the strings, you actually have to convert your newly create number, back to text (or variant), otherwise it cannot be in the same column, so nothing is gained:
select column1
,try_to_number(column1) as_num
,nvl(as_num::text, column1) as why_not_both
from values
('US15876'),
('1.106336965E9'),
('1.106336965'),
('1106336965');
COLUMN1
AS_NUM
WHY_NOT_BOTH
US15876
null
US15876
1106336965
1,106,336,965
1106336965
1.106336965
1
1
1106336965
1,106,336,965
1106336965

Related

In Amazon Redshift though I have specified service_date column as Date datatype but when I am taking date in IN operator it working with quotes only

select *
from nsclc_thought_spot
where patientid = 11000001
and service_date in ('2019-07-08', '2019-07-10')
order by patientid, service_date
is returning the results properly
But this is not working as expected:
select *
from nsclc_thought_spot
where patientid = 11000001
and service_date in (2019-07-08, 2019-07-10)
order by patientid, service_date
This query is not returning results.
If I have defined service_date column as date, then why do I have to pass the values in quotes inside IN operator in redshift?
Because 2019-07-08 means the integer 2019 minus the integer 7 minus the integer 8 which equals the integer 2004. Without quotes in SQL numbers are seen as numeric values. To be interpreted as something else you need to quote them (which is a text value) and then they need to be cast to the data type needed. In this case '2019-07-08' is a text value but Redshift will implicitly cast this to a date to make the comparison to the column data "service_date".
If you want to do this explicitly you can add the casting to the values - ... service_date IN ('2019-07-08'::date,'2019-07-10'::date) ... - which might make things clearer for you.

Check if character varying is between range of numbers

I hava data in my database and i need to select all data where 1 column number is between 1-100.
Im having problems, because i cant use - between 1 and 100; Because that column is character varying, not integer. But all data are numbers (i cant change it to integer).
Code;
dst_db1.eachRow("Select length_to_fault from diags where length_to_fault between 1 AND 100")
Error - operator does not exist: character varying >= integer
Since your column supposed to contain numeric values but is defined as text (or version of text) there will be times when it does not i.e. You need 2 validations: that the column actually contains numeric data and that it falls into your value restriction. So add the following predicates to your query.
and length_to_fault ~ '^\+?\d+(\.\d*)?$'
and length_to_fault::numeric <# ('[1.0,100.0]')::numrange;
The first builds a regexp that insures the column is a valid floating point value. The second insures the numeric value fall within the specified numeric range. See fiddle.
I understand you cannot change the database, but this looks like a good place for a check constraint esp. if n/a is the only non-numeric are allowed. You may want to talk with your DBA ans see about the following constraint.
alter table diags
add constraint length_to_fault_check
check ( lower(length_to_fault) = 'n/a'
or ( length_to_fault ~ '^\+?\d+(\.\d*)?$'
and length_to_fault::numeric <# ('[1.0,100.0]')::numrange
)
);
Then your query need only check that:
lower(lenth_to_fault) != 'n/a'
The below PostgreSQL query will work
SELECT length_to_fault FROM diags WHERE regexp_replace(length_to_fault, '[\s+]', '', 'g')::numeric BETWEEN 1 AND 100;

Insert values to a previous table in Qlik Sense

I'm trying to insert values in a tabla with values inside, like this table:
If you look at the column "202001" and row 22 at the end, it is null, so I want to insert manually any value.
It is null because that value it's not inserted to the database yet.
The expression I have is Sum([SH_historico_1.MONTO]/1000000) (Mounts..)
Any ideas? maybe with that SUM and then concadenate
Please try:
Alt(Sum([SH_historico_1.MONTO]/1000000),0)
where 0 is as you say "any value".
ALt function return first numeric value. So when your function will not return any number, another number is used.

RIGHT Function in UPDATE Statement w/ Integer Field

I am attempting to run a simple UPDATE script on an integer field, whereby the trailing 2 numbers are "kept", and the leading numbers are removed. For example, "0440" would be updated as "40." I can get the desired data in a SELECT statement, such as
SELECT RIGHT(field_name::varchar, 2)
FROM table_name;
However, I run into an error when I try to use this same functionality in an UPDATE script, such as:
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::varchar, 2);
The error I receive reads:
column . . . is of type integer but expression is of type text . . .
HINT: You will need to rewrite or cast the expression
You're casting the integer to varchar but you're not casting the result back to integer.
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::TEXT, 2)::INTEGER;
The error is quite straight forward - right returns textual data, which you cannot assign to an integer column. You could, however, explicitly cast it back:
UPDATE schema_name.table_name
SET field_name = RIGHT(field_name::varchar, 2)::int;
1 is a digit (or a number - or a string), '123' is a number (or a string).
Your example 0440 does not make sense for an integer value, since leading (insignificant) 0 are not stored.
Strictly speaking data type integer is no good to store the "trailing 2 numbers" - meaning digits - since 00 and 0 both result in the same integer value 0. But I don't think that's what you meant.
For operating on the numeric value, don't use string functions (which requires casting back and forth. The modulo operator % does what you need, exactly: field_name%100. So:
UPDATE schema_name.table_name
SET field_name = field_name%100
WHERE field_name > 99; -- to avoid empty updates

How to turn String to Numeric With Characters in it (Postgres)

I have a field that is a string that I want to turn into Numerics. Problem is that the field can contain characters and it's hard for me to do a simple regular expression replace. Here is an example,
field1
1
1.5
2adfk3
2. Section 2
0'#%0ls23
3.987
What I essentially want is if the field can be natively casted as a Numeric, then return the Numeric, otherwise return NULL. For example, I want another field, to be
field2
1
1.5
NULL
NULL
NULL
3.987
where field2 is now a numeric. What is the best way to do this?
In Excel I suppose this would be closest to IFERROR
You can do this with a case expression and a regex:
select column1,
case
when column1 ~ '^[0-9\.]+$' then column1::numeric
else null
end as column2
from the_table
The regex checks if the contents of the column consists only of numbers and a dot. If that is the case, the value can be cast to numeric value, otherwise it returns null