Wildcards using LTRIM in SQL Lite - sql

I'm trying to use LTRIM to split the following field 'hours' - trimming off the characters from the left up to and including the pipe | symbol.
Monday|11:00-18:00
to result in
11:00-18:00
I would have thought the following code is correct
LTRIM(hours, '%|')
But it just isn't working. The query runs but the above statement has no affect. Can anyone help?
Many thanks
Richard

Use instr() to compute the position of the pipe character in the string, and substr() to select everything after that position:
substr(col, instr(col, '|') + 1) as newcol
Demo on DB Fiddle:
with t as (select 'Monday|11:00-18:00' col)
select substr(col, instr(col, '|') + 1) as newcol from t
| newcol |
| :---------- |
| 11:00-18:00 |

Related

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]

How to trim data with last alphanumeric key as reference

Need your help on below Data trimming or what so ever to get the result that shows also on below. I want to get the data where my reference is the last - symbol.
See example below.
FROM TO
+-------------------------------+
|ABC-1234-AR-R | ABC-1234-AR |
|ABC-1254-AR-IT | ABC-1254-AR |
|ABC-1223-AR-LTL| ABC-1223-AR |
|ABC-1234-R | ABC-1234 |
+-------------------------------+
This will give you index of last occurence of a hyphen:
LEN(data) - CHARINDEX('-', REVERSE(data)) + 1
So it's enough to take substring of this length:
SELECT
data,
SUBSTRING(data, 1, LEN(data) - CHARINDEX('-', REVERSE(data))) AS data_trimmed
FROM yourTable;
Demo
You can also use a combination of LEFT and CHARINDEX functions.
Query
select [from],
left([from], len([from]) - charindex('-', reverse([from]), 1)) as [to]
from [your_table_name];
Find a demo here

Syntax error or access violation when using STRPOS with semicolon character

I have a table table1 with the following data
+----------------+
| model |
+----------------+
| a45/ a45m;aa45 |
| b34/b34m |
| c23;c23m/ cc23 |
+----------------+
I'm trying to clean up the model field with certain rules, such as
grab all characters before the first ;
from 1, grab all character before the first /
So I do the following in netezza for step 1
SELECT
SUBSTR(model, 1, STRPOS(model, ';')-1) AS model_clean
FROM table1
;
This throws error ERROR [42000] Syntax error or access violation. Any ideas why this is happening, does the character ; need to be escaped ?
One thing to note is that When I look for the space character as following, there is no error.
SELECT
SUBSTR(model, 1, STRPOS(model, ' ')-1) AS model_clean
FROM table1
;
Also is there a way to get step 2 also done in this same select statement ?
Expected output
+----------------+
| model_clean |
+----------------+
| a45 |
| b34 |
| c23 |
+----------------+
It fails because not all columns have semicolons, so strpos() returns 0. You can fix this just by adding a semicolon:
SELECT SUBSTR(model, 1, STRPOS(model || ';', ';') - 1) AS model_clean
Your query fails when you try to do substring with an invalid position, the result of strpos wich didn't found the semicolon.
You can use case statement to avoid calculate invalid position
Here are an example of SQLServer syntaxe ( charindex and strpos have reversed parameter order, up to you to reduce the query) http://sqlfiddle.com/#!18/55a6e/25
WITH step1
AS ( SELECT CASE
WHEN CHARINDEX(';', model) > 0 THEN SUBSTRING(model, 1, CHARINDEX(';', model) - 1)
ELSE model
END AS model
FROM table1 ),
step2
AS ( SELECT CASE
WHEN CHARINDEX('/', model) > 0 THEN SUBSTRING(model, 1, CHARINDEX('/', model) - 1)
ELSE model
END AS model
FROM step1 )
SELECT *
FROM step2;

How to extract the number from a string using Oracle?

I have a string as follows: first, last (123456) the expected result should be 123456. Could someone help me in which direction should I proceed using Oracle?
It will depend on the actual pattern you care about (I assume "first" and "last" aren't literal hard-coded strings), but you will probably want to use regexp_substr.
For example, this matches anything between two brackets (which will work for your example), but you might need more sophisticated criteria if your actual examples have multiple brackets or something.
SELECT regexp_substr(COLUMN_NAME, '\(([^\)]*)\)', 1, 1, 'i', 1)
FROM TABLE_NAME
Your question is ambiguous and needs clarification. Based on your comment it appears you want to select the six digits after the left bracket. You can use the Oracle instr function to find the position of a character in a string, and then feed that into the substr to select your text.
select substr(mycol, instr(mycol, '(') + 1, 6) from mytable
Or if there are a varying number of digits between the brackets:
select substr(mycol, instr(mycol, '(') + 1, instr(mycol, ')') - instr(mycol, '(') - 1) from mytable
Find the last ( and get the sub-string after without the trailing ) and convert that to a number:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE test ( str ) AS
SELECT 'first, last (123456)' FROM DUAL UNION ALL
SELECT 'john, doe (jr) (987654321)' FROM DUAL;
Query 1:
SELECT TO_NUMBER(
TRIM(
TRAILING ')' FROM
SUBSTR(
str,
INSTR( str, '(', -1 ) + 1
)
)
) AS value
FROM test
Results:
| VALUE |
|-----------|
| 123456 |
| 987654321 |

SQL View SUBSTRING and CHARINDEX

I have a query in SQL 2008
SELECT [orde_reference],
SUBSTRING([orde_reference],
CHARINDEX('/', [orde_reference]) + 1,
LEN([orde_reference])) AS batch
FROM Orders
That returns the following
orde_reference: 27777/2012/1
batch: 2012/1
However I need the batch to just be the characters after the last / (there are always 2 x '/' in the varchar
orde_reference: 27777/2012/1
batch: 1
Any help would be appreciated.
Cheers
Mim
Try
SELECT orde_reference,
RIGHT(orde_reference, CHARINDEX('/', REVERSE(orde_reference)) - 1) batch
FROM orders
Sample output:
| ORDE_REFERENCE | BATCH |
--------------------------
| 27777/2012/1 | 1 |
| 27734/2013/11 | 11 |
Here is SQLFiddle demo
As there are always 2 / you can pass the optional third argument to CHARINDEX (start_location) to tell it to start looking after the first one.
SELECT [orde_reference],
SUBSTRING([orde_reference],
CHARINDEX('/', [orde_reference],1 + CHARINDEX('/', [orde_reference])) + 1,
LEN([orde_reference])) AS batch
FROM Orders
You would be better off storing these components individually however in separate columns.
Use REVERSE twice ;)
SELECT [orde_reference]
,REVERSE(SUBSTRING(reverse([orde_reference]), 0, CHARINDEX('/', reverse([orde_reference])))) AS batch
from (values(
' 27777/2012/123'
)) as O([orde_reference])