Snowflake if String Pattern replace - sql

I have column which should only contain numbers[0-9], But in some cases we started see alphanumeric[eg:p8eSadfghrc] values in that column.
I wanna write a condition where if the value is not completely numeric{0-9}, i wanna replace it with another value from another column.

Something like this?
update t
set col = <other value>
where regexp_like(col, '[^0-9]');
This updates the data. You could also just do this in a query:
select t.*,
(case when regexp_like(col, '[^0-9]') then <other value> else col end)
from t;

In Snowflake, I would recommend try_to_decimal(). It attempts to convert the number to a decimal value (you control the target precision and scale with arguments) and rturns null if that fails:
select t.*, case when try_to_decimal(mycol) is null then myothercol else mycol end newcol
from mytable
If you want an update statement:
update mytable
set mycol = myothercol
where try_to_decimal(mycol) is null
When given no second and third argument, the number of allowed digits is 38, with 0 decimals (which seems to be what you want).

Related

How do I update a SQL table to strip away the left 3 characters in a 9 character string?

I have a table with values like this in columnA:
ColumnA
800
800602041
800602044
800602050
800602057
800602093
800602099
800602131
800602132
800602133
I need to strip away the leading 800 but leave the rest of the numbers intact. I tried doing an update with wildcards but it failed. I have several tables with thousands of records that need this correction.
The result would look like this:
ColumnA
800
602041
602044
602050
602057
602093
602099
602131
602132
602133
I cannot lose the single 800 record which is why I was trying an update query with wildcards. I only want to update the rows with a 9 digit value that begins with 800.
Kindly try using below-mentioned query.
Consider table name as #a and column name as colA.
Update #a set colA = case when len(ltrim(rtrim(cola)))<=3 then colA else right(colA, len(ltrim(rtrim(colA)))-3) end
Select * from #a
A typical method is:
(case when columnA like '800%' then substring(columnA, 4, 6) else columnA) as new_columnA
Note: This preserves values when the value does not start with 800. And substring() might be spelled substr() in your database.
Since the data values are stored as numbers, I ended up treating it like a math problem.
BEGIN TRAN
SET XACT_ABORT ON
UPDATE sometable
SET ColumnA = ColumnA - 800000000
WHERE ColumnA LIKE '8006%'
It is not sophisticated but it worked.
UPDATE YourTable
SET ColumnA = SUBSTRING(ColumnA, 4, LEN(ColumnA))
WHERE LEN(ColumnA) = 9 AND ColumnA LIKE '800%'
A mass update would look like this with the information you have provided. Update ColumnA and take the entire value starting at the 4th character. Only do this when the length of ColumnA is equal to 9 and is prefixed with 800.
Filter the records by checking the string length which are exactly 9 digits and which starts with characters '800'. Same can be achieved with help of LEFT/RIGHT function.
UPDATE data_table
SET columnA = right(columnA,6)
WHERE LEN(columnA) = 9 AND left(columnA,3) = '800'
Note: Consider "data_table" as your actual table and "columnA" as the column you want to update.

How to use Decode Function in the case where column has string values

I have a view xxabc_v (shown below), I need to update the "Code" column to Null wherever it is N/A when "Value" column sum (900+(-900)=0) becomes zero for the "field_name" values (Demand A+Demand B) for the "Date" 01-Apr-21.
How can I put the decode logic to code column in the above case?
Table structure and expected output:
You don't want decode() because a much simpler method works:
select nullif(code, 'N/A')
This returns NULL when code takes on the specified value.
If you actually want to change the data, then you want update:
update t
set code = NULL
where code = 'N/A';
EDIT:
I see, you have an extra condition. So, use case:
(case when code = 'N/A' and
sum(value) over (partition by id, date) = 0
then NULL
else code
end)
I assumed that you need date wise id wise sum when to sum(). Please check this out:
select date,id,(case when sum(value)over(partition by date,id)=0 and code='N/A' then NULL
else Code end)code, field_name,value
from tablename

How to quickly compare many strings?

In SQL Server, I have a string column that contains numbers. Each entry I need is only one number so no parsing is needed. I need some way to find all rows that contain numbers from 400 to 450. Instead of doing:
...where my stringcolumn like '%400%' or stringcolumn like '%401%' or stringcolumn like '%402%' or ...
is there a better that can save on some typing?
There are also other values in these rows such as: '5335154', test4559#me.com', '555-555-5555'. Filtering those out will need to be taken into account.
...where stringcolumn like '4[0-4][0-9]' OR stringcolumn = '450'
You don't need the wildcard if you want to restrict to 3 digits.
Use regex to accomplish this.
...where stringcolumn like '4[0-4][0-9]' OR stringcolumn like '450'
one way
WHERE Column like '%4[0-4][09]%'
OR Column LIKE '%500%'
keep in mind that this will pick anything with the number in it, so 5000 will be returned as well
I would do the following:
select t.*
from (select t.*,
(case when charindex('4', col) > 0
then substrint(col, charindex('4', col), charindex('4', col) + 2)
end) as col4xx
from t
) t
where (case when isnumeric(col4xx) = 1
then (case when cast(col4xx as int) between 400 and 450 then 'true'
end)
end) = 'true'
I'm not a fan of having case statements in WHERE clauses. However, to ensure conversion to a number, this is needed (or the conversion could become a column in another subquery). Note that the following is not equivalent:
where col4xx between '400' and '450'
Since the string '44A' would match.

postgresql - exclude any result with nulls

I'm doing a bunch of sum queries: SELECT col1 + col2 + col3 + ...
Some of the values in some of the columns are null. I'm checking for them by doing
SELECT CASE WHEN col1 is not null and col2 is not null and ...
I'm wondering if there is a more concise syntax for accomplishing this task.
Well, since the sum of any number and null is null, you can do something like the following (with the obvious ... filled in):
select big_honking_sum
from(
select col1+col2+col3+...+coln as big_honking_sum
from some_table
)sum
where big_honking_sum is not null;
Use COALESCE function if you can accept that a NULL value will be treated as 0.
SELECT COALESCE(Col1,0)
+ COALESCE(Col2,0)
+ COALESCE(Col3,0)
AS TOTAL FROM table;
Perhaps you could consider using 0 as default value instead of NULL if applicable.
You can have that even simpler:
SELECT foo
FROM ...
WHERE (-1 IN (col1, col2, col3)) IS NOT NULL
The IN expression will return NULL if (and only if) there is at least one NULL value among the tested values (and no match). So the whole expression evaluates to TRUE if (and only if) there is no NULL.
Edit: I have to correct myself! A positive match would stop the evaluation and return TRUE, even if a NULL is among the values. So you need a value that is guaranteed not to be in the set. Like 0 where all values are > 0 or -1 where all values are positive or you cannot use this expression for the purpose.

Oracle NVL problem

I'm trying to pass a null value as something else in my db and it seems to work without a Where clause like so
select NVL(column1, '0') column1 from table1
produces this
0 test1
0 test2
1 test3
But when I add the where clause like so
select NVL(column1, '0') column1 from table1 where column1 <=1
it produces this
1 test3
But now if I add the following to the query it works
select NVL(column1, '0') column1
from table1
where NVL(column1, '0') <=1
But it seems like a long way round to get the value to show correctly with a Where clause
Any ideas what i'm doing wrong?
Thanks in advance
You cannot refer to an alias defined in the SELECT list from the WHERE clause. So if you apply the NVL function in the SELECT list, you'd need the same function call in the WHERE clause (as you've demonstrated) or you would need to apply the function in an inline view
SELECT column1
FROM (SELECT nvl(column1, 0) column1
FROM table1)
WHERE column1 <= 1
Note that for general sanity, if COLUMN1 is a NUMBER, the second parameter to NVL should also be a NUMBER. Otherwise, you're going to do implicit conversions and your comparison operations may end up using string comparison semantics rather than numeric comparison semantics. Since the string '12' is less than the string '2', that can lead to unexpected results.
you have shown the correct way.
an alternative would be to say
OR column IS NULL