Oracle - Divide a string based on total length of string - sql

I have a non standardized data in one of the column and I need to be splitting the data into 3 parts.
there is no specific requirement on length each column should have. It's just that the entire data to be split into 3
Input Data 01 : test , test ,test/test
Input data 02: Test; test,test\testing123data123datadatatawerr
OutPut 01: Col1=test Col2= test,test Col3=/test
Output 02: Col1= Test; col2= test,test col3=\testing123data123datadatatawerr
Is there a way to take the total length and based on that divide into 3 parts.
Concatenating of split data I need to get the entire string back.

I need to be splitting the data into 3 parts. there is no specific requirement on length each column should have
The simplest approach is to use substr():
select
substr(col, 1, 1) col1,
substr(col, 2, 1) col2
substr(col, 3) col3
from mytable
The first two columns contain one character each, starting from the beginning of the string; the last column contains the reminder. This guarantees that each column will be fed (provided that the string is at least 3 characters).
On the other hand if you want to split in three parts whose length is close to equal, you can do:
select
substr(col, 1, round(length(col) / 3)) col1,
substr(col, 1 + round(length(col) / 3), round(length(col) / 3)) col2
substr(col, 1 + 2 * round(length(col) / 3)) col3
from mytable

Related

How to pull a value in between multiple values?

I have a column named Concatenated Segments which has 12 segment values, and I'm looking to edit the formula on the column to only show the 5th segment. The segments are separated by periods.
How would I need to edit the formula to do this?
Would using a substring work?
Alternatively, using good old SUBSTR + INSTR combination
possibly faster on large data sets
which doesn't care about uninterrupted strings (can contain anything between dots)
SQL> WITH
2 -- thank you for typing, #marcothesane
3 indata(s) AS (
4 SELECT '1201.0000.5611005.0099.211003.0000.2199.00099.00099.0000.0000.00000' FROM dual
5 )
6 select substr(s, instr(s, '.', 1, 4) + 1,
7 instr(s, '.', 1, 5) - instr(s, '.', 1, 4) - 1
8 ) result
9 from indata;
RESULT
------
211003
SQL>
Use REGEXP_SUBSTR(), searching for the 5th uninterrupted string of digits, or the 5th uninterrupted string of anything but a dot (\d and [^\.]) starting from position 1 of the input string:
WITH
-- your input ... paste it as text next time, so I don't have to manually re-type it ....
indata(s) AS (
SELECT '1201.0000.5611005.0099.211003.0000.2199.00099.00099.0000.0000.00000' FROM dual
)
SELECT
REGEXP_SUBSTR(s,'\d+',1,5) AS just_digits
, REGEXP_SUBSTR(s,'[^\.]+',1,5) AS between_dots
FROM indata;
-- out just_digits | between_dots
-- out -------------+--------------
-- out 211003 | 211003

How to split string based on column length and insert into table

I have a string that I need to split and create table from it.
00001 00000009716496000000000331001700000115200000000000
I know the exact length of each column:
Col1 = 5
Col2 = 7
Col3 = 23
etc...
I need something like this (Empty values are NULL's)
Can you direct me to the right way of doing that?
Use substring():
select substring(col, 1, 5) as col1,
substring(col, 6, 2) as col2,
. . .
you can use computed column to improve your performance(visit https://www.sqlservertutorial.net/sql-server-basics/sql-server-computed-columns/)
use below function to fill your column
SUBSTRING(string, start, length)

Ordering Postgresql query result on Housenumber column by custom comparer

I'm using postgresql as DB.
Using my query to select column housenumber of varchar type(and some other columns) from table with buildings info. So I want the result to be ordered other way, rather then string comparison.
For example, if I have following results:
"1"
"1 block2"
"1 b30"
"1 b3"
"1 b3 s4"
"10"
"2"
I want this result to be sorted by following logic:
1) getting source string "1 b3 s4"
2) split it into ["1" , "b3" , "s4"]
3) try to parse all substrings to integer, ignoring letters, which
are not numbers into [1 , 3, 4]
4) calculate bigger number for future sorting as
1 * 1000000 + 3 * 1000 + 4 = 1003004.
Is this possible and how could I implement this methoad and use it for sorting query result?
Here is my sql query(shorted):
SELECT housenumber, name
FROM osm_buildings
where
housenumber <> ''
order by housenumber
limit 100
I'm not sure why you would want to convert to some big integer for sorting. You can do the following:
Remove all characters that are not digits or spaces.
Convert to an array, splitting on one or more spaces.
Convert the array to an integer array.
Then you can can sort on this:
order by regexp_split_to_array(regexp_replace(v.addr, '[^0-9 ]', '', 'g'), ' +')::int[]
You can store this as a value in a table, if you want to persist it.
Here is a db<>fiddle.

SQL Server: How to display a specific character based on position in a column

So I'm attempting to display a single character based on its position in a string from one column. Since this is grid data, there is a simple math to it. The grid has 24 rows 'A-X', and 44 columns.
So lets say I want to see the value in D9. I already know the expected value should be a 'A1', so that means the character length is '2'. If I do the math: (A + B + C = 3 x 44, + 9). That two-character value for D9 starts at the 141st position of that string in Col2. I attempted to use SUBSTRING with no success
SELECT
Col1 , SUBSTRING('Col2',141,2)
FROM Table1
Query result displays data in Col1, but for Col2 its just blank. What am I missing?
Asked too soon. Figured out I had to remove the ' from the column name
SELECT
Col1 , SUBSTRING('Col2',141,2)
FROM Table1
Didn't work
SELECT
Col1 , SUBSTRING(Col2,141,2)
FROM Table1
Works

SQL - Combine two strings having the second string always right aligned

I'm currently trying to attain alignment via SQL queries when combining two columns.
my current data set looks something like:
Col1 Col2
usd US Dollar
cad Canadian Dollar
mxn Mexican Peso
And I want to combine col1 + col2, but no matter how many characters are in col2, the data that comes out of col1 needs to always be aligned to the right in the display.
The display is limited at 49 characters. Col2 has no specific limit as it's a description column, while col1 is a percentage column so it will have a maximum of 7 characters: 100.00%
Any help will be appreciated.
Thanks
If I understood your question well and assuming that col1 has maximal length of 7 characters while col2 length is undetermined, the following query should give you the results needed:
SELECT
ISNULL(myTable.col1, '')
+ (CASE WHEN LEN(ISNULL(myTable.col2, '')) < 49 - LEN(ISNULL(myTable.col1, ''))
THEN SPACE(49 - LEN(ISNULL(myTable.col1, '')) - LEN(ISNULL(myTable.col2, '')))
+ ISNULL(myTable.col2, '')
ELSE ' ' + LEFT(ISNULL(myTable.col2, ''),
49 - LEN(ISNULL(myTable.col1, '')) - 1)
END) AS cols_for_49chars_display
FROM
myTable
Since col1 is assumed to have max length of 7 characters, the CASE statement verifies the length of col2 for specific row.
If it's lower than 49 - LEN(col1), prepend col2 with 49 - LEN(col1) - LEN(col2) spaces using TSQL SPACE function (docs here) to right-align col2 and then add col2 itself.
In opposite case add one space after col1 and left-cut col2 to the length of 49 - LEN(ISNULL(myTable.col1, '')) - 1 when 1 being the length of the added single space character.
Example input data and results of the query:
Lets take as an example the data provided in your answer adding an extra row to show what will happen when col2 value is too long:
myTable contents:
col1 col2
------------------------------------------------------------------------------------------------
usd US Dollar
cad PCanadian Dollar
mxn Mexican Peso
dummy Very long description of a "dummy" currency that in fact doesn't exist in the real world
The result of the query on above rows would be:
cols_for_49chars_display
-------------------------------------------------
usd US Dollar
cad PCanadian Dollar
mxn Mexican Peso
dummy Very long description of a "dummy" currency
I hope it helps at least slightly.