Get value in string after 4th space SQL - sql

Related question so now I have a table Test with 3 columns id, value and term
TEST
id
value
Item
1
AB CD EF GH IJ KL
1 4 78 78 10 9
I will like a query to get the value in the Item column after the 4th space. In this case that will correspond to 'IJ' in the value column and in the "Item' column it will return '10'
This is what i tried
select
substring(item(REGEXP_COUNT( SPLIT( TRIM(REGEXP_REPLACE(value, '[^[:digit:]]', ' ')), 'IJ')[0] , ' ')
from Test

Use split_part()
select split_part('AB CD EF GH IJ KL', ' ',5);
This function split the string on the chosen character and allows you to choose which one you'd like to return as a string. In this case, the 5th part.

Related

Count spaces before a string value SQL

so I have a table TEST with 2 columns - id and value. I would like a count of the number of spaces before a specific string value.
id value
1 AB CD EFD RA
I would like a query to count the number of spaces in the value column to the left of "EFD". In this case it should be 2.
Thanks!
I tried:
select ID,
VALUE,
regexp_substr(Value, 'EFD') AS "SUBSTRING",
regexp_instr(Value, 'EFD') AS "POSITION"
I would like to get the position of EFD in this array as well. I should get 3.
select id, value,
regexp_substr(Value, 'EFD') AS substring,
regexp_count(substring(Value, 1, regexp_instr(Value, 'EFD')-1), ' ') AS spaces_before_EFD,
regexp_instr(Value, 'EFD') AS position
from test;

SQL How to search text field for 2nd without matching 22nd, etc?

I want to query for numbered street names that can occur anywhere within a text column, and filter out matches for numbered street names with more digits, i.e. 2nd but not 42nd, 182nd, etc. Is there any method more graceful or simplified than combination of:
WHERE col LIKE '2nd%' OR col LIKE '% 2nd%'
As long as the 2nd doesn't occur at the beginning of the string, you can just check that the character before it is not a digit using
col LIKE '%[^0-9]2nd%'
For example:
select col, case when col like '%[^0-9]2nd%' then 'second' else 'not' end as test
from (values ('12 2nd st'), ('45 42nd st'), ('128 22nd st')) test(col)
Output:
col test
12 2nd st second
45 42nd st not
128 22nd st not
Nick's answer is very good, but it doesn't handle the case when '2nd' appears at the beginning of a string. This is easily handled by pre-pending a character on the column being compared:
' ' + col LIKE '%[^0-9]2nd%'

Sorting like excel in postgres

I have a column in a table whose values are,
a100,a7,a20,16,17,bbb,ccc,15kk,24dd
I want to sort this column and expected result (same like excel) is,
16,17,15kk,24dd,bbb,ccc,a7,a20,a100
i.e.:
Empty first then numeric then alpha-numeric then alphabetical then alphanumeric.
I have tried multiple solutions from google but all failed. Most of the solution are mixing numeric and alpha-numeric together like 15kk, 16, 17.
Something like this:
with data (nr) as (
values ('a100'),('a7'),('a20'),('16'),('2'),('17'),('bbb'),('ccc'),('15kk'),('24dd')
)
select *
from data
order by case
when nr ~ '^[0-9]+$' then 1
when nr ~ '^[0-9]+[a-z]+$' then 2
when nr ~ '^[^0-9]+$' then 3
when nr ~ '^[a-z]+[0-9]+' then 4
end,
case
when nr ~ '^[0-9]+$' then nr::integer
when nr ~ '^[0-9]+[a-z]+$' then regexp_replace(nr, '[^0-9]+', '', 'g')::integer
else 0
end,
nr;
The above returns:
nr
----
2
16
17
15kk
24dd
bbb
ccc
a100
a20
a7
The first case creates "groups" based on the structure of the value,
The second case makes sure that the "real" numbers are sorted according to their numeric values to make '16' sort after '2'.
And the final nr sorts the alphanumeric values inside the groups
Online example: http://rextester.com/JMG51196

SQL Server extract specific value from string which can contain duplicates/nulls

I am trying to find the best way to extract specific values from a string which can contain nulls/duplicates for the values. The issue is I have to do this in a query and pull those values into a view for use down the line.
Example of the string:
ABCD: 123 EFG: 03 HIJ: NGAB XYZ: XYZ: 133
EFG: 03 HIJ: NGAB XYZ: 133
I am trying to extract the values for ABCD, EFG, HIJ, and XYZ.
For example, the first string should return:
123 (for value of ABCD)
03 (for value of EFG)
NGAB (for value of HIJ)
133 (for value of XYZ)
Second string should return:
NULL (for value of ABCD)
03 (for value of EFG)
NGAB (for value of HIJ)
133 (for value of XYZ)
The length of the values to return are always static (i.e. ABCD will always be ABCD and 123 will always be the length of the value to return - i.e 3 characters. Same applies for EFG and 03 - EFG will always be EFG and 03 will always be 2 characters and so on).
I am trying to use below to try and return my values:
SELECT substring(replace(replace(TEMPFIELD,' ',''),':',''), charindex('XYZ',replace(replace(TEMPFIELD,' ',''),':',''))+3,3) AS XYZ FROM MYTABLE
I change my query per field and adjust the length on the substring as needed. The issue is that when there are duplicates, I return the wrong values and when there are nulls, I return the wrong value.
For example, my query returns XYZ as the value of XYZ in the first string instead of 123. It also returns 03H as the value of ABCD in the second string instead of NULL. Is there a better function for me to use in this case to handle both scenarios of nulls/duplicates?
Updated query:
SELECT CASE WHEN TEMPFIELD LIKE '%XYZ%XYZ%'
THEN substring(stuff(replace(replace(TEMPFIELD ,' ',''),':',''),charindex('XYZ',replace(replace(TEMPFIELD ,' ',''),':','')),3,''), charindex('XYZ',stuff(replace(replace(TEMPFIELD ,' ',''),':',''),charindex('XYZ',replace(replace(TEMPFIELD ,' ',''),':','')),3,''))+3,3)
WHEN TEMPFIELD LIKE '%XYZ%'
THEN substring(replace(replace(TEMPFIELD ,' ',''),':',''), charindex('XYZ',replace(replace(TEMPFIELD ,' ',''),':',''))+3,3)
ELSE NULL
END AS XYZ
Ideally if you can you would want to sort out the string you are trying to pass as this could get very messy, but I can offer you this solution, based on the following assumptions:
Duplicated keys only occur twice as per your example
The values cannot contain the key
That when the keys are duplicated that the last one is the value you want.
CASE WHEN TEMPFIELD LIKE '%XYZ%XYZ%'
THEN SUBSTRING(TEMPFIELD, CHARINDEX('XYZ: ', TEMPFIELD, CHARINDEX('XYZ: ', TEMPFIELD) + 1) + 5, 3)
WHEN TEMPFIELD LIKE '%XYZ%'
THEN SUBSTRING(TEMPFIELD, CHARINDEX('XYZ: ', TEMPFIELD) + 5, 3)
ELSE NULL
END AS XYZ
Add in the replacements if you really need to but if you know the format is reliable enough you shouldn't need to do this as it will just add processing time.
To explain what this does a bit: the first case statement will deal with the duplicated values by getting the CHARINDEX of the second key, if that case criteria does not match then it will fall to the second case and do something similar to what you were already doing and finally if the string does not match either of those it simply gives you null.

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