SQL change number format to custom "0000000000000000" from any integer number in SELECT statement - sql

I am trying write a SQL SELECT statement in Snowflake where I need to select a column 'xyz' form table 'a'(select xyz from a). Although, the number in column xyz is formatted into 6,7,8 digits and I want to convert that in select statement itself to 16 digits with leading 0's. I used concat() but since the column contains either 6,7,8 digits I am not able to format it into max 16 digits with leading 0's.
Note: I need it to be in select statement as I cant update the column in the database to 16 digit format.
Example
Input: 123456, 1234567, 12345678
Output should be: 0000000000123456, 0000000001234567, 0000000012345678
Can someone help me out here please. Thanks!

Using TO_VARCHAR with format provided:
SELECT TO_VARCHAR(12345, '0000000000000000');
WITH cte(c) AS (
SELECT * FROM (VALUES (123456), (1234567),(12345678))
)
SELECT c, TO_VARCHAR(c, '0000000000000000') AS result
FROM cte;
Output:

with data(c) as (
select * FROM (
values (12345), (293848238), (284), (239432043223432)
)
)
select lpad(c, 16, '0') as c from data;
+------------------+
| C |
|------------------|
| 0000000000012345 |
| 0000000293848238 |
| 0000000000000284 |
| 0239432043223432 |
+------------------+

If you want dynamic width, or to stick to a form of CONCAT then here are some extra ways.
SELECT column1,
TO_CHAR(column1, '0000000000000000') as fixed_width,
TO_CHAR(column1, REPEAT('0', 16)) as dynamic_width,
RIGHT(REPEAT('0', 16) || column1::text, 16) as another_way,
LPAD(column1, 16, '0')
FROM VALUES
(123456),
(1234567),
(12345678),
(12345.678),
(1234567890123456789)
COLUMN1
FIXED_WIDTH
DYNAMIC_WIDTH
ANOTHER_WAY
LPAD(COLUMN1, 16, '0')
123,456
0000000000123456
0000000000123456
000000123456.000
000000123456.000
1,234,567
0000000001234567
0000000001234567
000001234567.000
000001234567.000
12,345,678
0000000012345678
0000000012345678
000012345678.000
000012345678.000
12,345.678
0000000000012346
0000000000012346
000000012345.678
000000012345.678
1,234,567,890,123,456,789
################
################
890123456789
1234567890123456
the two TO_CHAR/TO_VARCHAR methods don't deal with floating results, where-as the RIGHT version does. But that doesn't handle values that are larger the 16 DP
Using you SQL
So using the SQL you put in your comment, and then using 2 CTE's for fake out some data AND using one of the many answers to your question, we get:
WITH "abc" as (
SELECT * FROM VALUES
(123456),
(1234567)
t(ki)
), "xyz" as (
SELECT * FROM VALUES
(6, 123456),
(7, 1234567)
t(ki_value, piv_id)
)
SELECT DISTINCT
y.kI,
yo.ki_value,
yo.piv_num
FROM "abc" as y
left join (
select
ki_value,
LPAD(piv_id, 16, '0') as piv_num
--concat('0000000000',piv_id) as piv_num
from "xyz"
) as yo on y.KI = yo.piv_num
WHERE y.KI in (123456,1234567)
this gives:
KI |KI_VALUE |PIV_NUM
--|--|--
123,456 |6 |0000000000123456
1,234,567 |7 |0000000001234567
So this "works" but as your SQL is written, it's really bad. The WHERE statement is checking the values are numbers and are in the range, why on earth are you want to string pad numbers as TEXT with however many number of zeros in front, because you should leave them as numbers.

Related

How to replace rows containing alphabets and special characters with Blank spaces in snowflake

I have a column "A" which contains numbers for example- 0001, 0002, 0003
the same column "A" also contains some alphabets and special characters in some of the rows for example - connn, cco*jjj, hhhhhh11111 etc.
I want to replace these alphabets and special characters rows with blank values and only want to keep the rows containing the number.
which regex expression I can use here?
If you want to extract numbers from these values (even if they end or start with non digits), you may use something like this:
create table testing ( A varchar ) as select *
from values ('123'),('aaa123'),('3343'),('aaaa');
select REGEXP_SUBSTR( A, '\\D*(\\d+)\\D*', 1, 1, 'e', 1 ) res
from testing;
+------+
| RES |
+------+
| 123 |
| 123 |
| 3343 |
| NULL |
+------+
I understand that you want to set to null all values that do not contain digits only.
If so, you can use try_to_decimal():
update mytable
set a = null
where a try_to_decimal(a) is null
Or a regexp match:
update mytable
set a = null
where a rlike '[^0-9]'

PostgreSQL - Extract string before ending delimiter

I have a column of data that looks like this:
58,0:102,56.00
52,0:58,68
58,110
57,440.00
52,0:58,0:106,6105.95
I need to extract the character before the last delimiter (',').
Using the data above, I want to get:
102
58
58
57
106
Might be done with a regular expression in substring(). If you want:
the longest string of only digits before the last comma:
substring(data, '(\d+)\,[^,]*$')
Or you may want:
the string before the last comma (',') that's delimited at the start either by a colon (':') or the start of the string.
Could be another regexp:
substring(data, '([^:]*)\,[^,]*$')
Or this:
reverse(split_part(split_part(reverse(data), ',', 2), ':', 1))
More verbose but typically much faster than a (expensive) regular expression.
db<>fiddle here
Can't promise this is the best way to do it, but it is a way to do it:
with splits as (
select string_to_array(bar, ',') as bar_array
from foo
),
second_to_last as (
select
bar_array[cardinality(bar_array)-1] as field
from splits
)
select
field,
case
when field like '%:%' then split_part (field, ':', 2)
else field
end as last_item
from second_to_last
I went a little overkill on the CTEs, but that was to expose the logic a little better.
With a CTE that removes everything after the last comma and then splits the rest into an array:
with cte as (
select
regexp_split_to_array(
replace(left(col, length(col) - position(',' in reverse(col))), ':', ','),
','
) arr
from tablename
)
select arr[array_upper(arr, 1)] from cte
See the demo.
Results:
| result |
| ------ |
| 102 |
| 58 |
| 58 |
| 57 |
| 106 |
The following treats the source string as an "array of arrays". It seems each data element can be defined as S(x,y) and the overall string as S1:S2:...Sn.
The task then becomes to extract x from Sn.
with as_array as
( select string_to_array(S[n], ',') Sn
from (select string_to_array(col,':') S
, length(regexp_replace(col, '[^:]','','g'))+1 n
from tablename
) t
)
select Sn[array_length(Sn,1)-1] from as_array
The above extends S(x,y) to S(a,b,...,x,y) the task remains to extracting x from Sn. If it is the case that all original sub-strings S are formatted S(x,y) then the last select reduces to select Sn[1]

Extract Value from a string PostgreSQL

Simple Question
I have the following type of results in a string field
'Number=123456'
'Number=1234567'
'Number=12345678'
How do I extract the value from the string with regard that the value can change between 5-8 figures
So far I did this but I doubt that fits my requirement
SELECT substring('Size' from 8 for ....
If I can tell it to start from the = sign till the end that would help!
The likely simplest solution is to trim 7 leading characters with right():
right(str, -7)
Demo:
SELECT str, right(str, -7)
FROM (
VALUES ('Number=123456')
, ('Number=1234567')
, ('Number=12345678')
) t(str);
str | right
-----------------+----------
Number=123456 | 123456
Number=1234567 | 1234567
Number=12345678 | 12345678
You could use REPLACE:
SELECT col, REPLACE(col, 'Number=', '')
FROM tab;
DBFiddle Demo
Based on this question:
Split comma separated column data into additional columns
You could probably do the following:
SELECT *, split_part(col, '=', 2)
FROM table;
You may use regexp_matches :
with t(str) as
(
select 'Number=123456' union all
select 'Number=1234567' union all
select 'Number=12345678' union all
select 'Number=12345678x9'
)
select t.str as "String",
regexp_matches(t.str, '=([A-Za-z0-9]+)', 'g') as "Number"
from t;
String Number
-------------- ---------
Number=123456 123456
Number=1234567 1234567
Number=12345678 12345678
Number=12345678x9 12345678x9
--> the last line shows only we look chars after equal sign even if non-digit
Rextester Demo

Getting string from rightside 10 char

My table is in oracle toad. teh table contain column name phone number varchar2 datatype.it contain set of phonenumbers. some numbers are more than 10 char. i want to filter that number from right side 10 char.
data's in the table
-------------------
phone number
9948184759
9948220955
994823298612
9948249815
99482599971234
9948277935
9948288258
99483015076789
9948335085
9948337552
9948338134
the above column values are phone numbers.but some numbers are more than 10 char length
that numbers are
----------------
994823298612
99482599971234
99483015076789
expected output for the above numbers
----------------------------------------
4823298612
2599971234
3015076789
Help me to do this? am new to oracle toad
Simpler:
select substr(phone_number, -10) from ...
You can achieve that by using Substr function for example
with T1 as
(
select 99482599971234 n from dual union all
select 99483015076789 n from dual union all
select 994823298612 n from dual
)
select substr(n, Length(n) - 9, 10) nn
from t1
Nn
-------------------
4823298612
2599971234
3015076789

Find similar data from different columns in Oracle

I have two columns like this. (TC_NO is 11 character, VER_NO is 10 character)
TC_NO VER_NO
19262512794 1926251279
31124177286 1111111111
31067179194 2222222222
65617278204 6561727820
31483188084 0000000000
What i want is, finding VER_NO's first 10 character is the same TC_NO's first 10 characters..
For example for this table the result should be:
TC_NO VER_NO
19262512794 1926251279
65617278204 6561727820
How can I do that in Oracle?
select *
from MYTABLE
where substr(TC_NO,1,10) = VER_NO
Assuming you dont have nulls.
select *
from MYTABLE
where substr(TC_NO,1,10)=substr(VER_NO, 1, 10);
If you have nulls and you want them to be equal.
select *
from MYTABLE
where substr(NVL(TC_NO, '-'),1,10)=substr(NVL(VER_NO, '-'), 1, 10);
If you have nulls and you dont want them to be equal.
select *
from MYTABLE
where substr(NVL(TC_NO, '-'),1,10)=substr(NVL(VER_NO, '|'), 1, 10);