SQL - Extracting a substring between two characters - sql

I am trying to pull out the name of a city from a long string in my database. Here is an example of what the data looks like for a few different locations.
"701 MONROE STREET NW RUSSELLVILLE, AL 35653 (34.514971, -87.736372)"
"1825 HOLTVILLE ROAD WETUMPKA, AL 36092 (32.558544, -86.221265)"
I want to create a column for just the Name of the city. My thought was was to take everything Left of the fir comma and right of the following space. I have tried a few different ways to pull this but thing I might be missing something.
SELECT left(Location, CHARINDEX(',', location)) as city FROM table
This is returning everything left of the first comma.
"701 MONROE STREET NW RUSSELLVILLE,
"1825 HOLTVILLE ROAD WETUMPKA,
But now I want to return everything left of the comma and everything Right of the last space in this string and I am stumped as to how I would pull that information correctly. Any help would be appreciated.
Thanks,
Pat

Using REVERSE could work with something along the lines of:
SELECT reverse(
left(
reverse(
left(
Location,
CHARINDEX(',', location)-1
)
),
CHARINDEX(' ', reverse(
left(
Location,
CHARINDEX(',', location)-1
)
)
)
)
)as city FROM table;
Fiddle

If the Google API mentioned in my comment above is not an option. You can download (or even purchase) a ZIP Code database. The cost is nominal. I would suggest the quarterly updates because ZIP Codes change over time (add/edit/delete)
Example
Declare #YourTable table (id int,addr varchar(250))
Insert Into #YourTable values
(1,'701 MONROE STREET NW RUSSELLVILLE, AL 35653 (34.514971, -87.736372)'),
(2,'1825 HOLTVILLE ROAD WETUMPKA, AL 36092 (32.558544, -86.221265)')
Select A.ID
,StreetAddress =left(addr,nullif(charindex(Z.CityName,addr),0)-1)
,Z.CityName
,Z.StateCode
,Z.ZIPCode
From #YourTable A
Join [dbo].[OD-Zip] Z
on Z.ZipCode = substring(addr,nullif(patindex('%[0-9][0-9][0-9][0-9][0-9]%',addr),0),5)
and charindex(Z.CityName,addr)>0
and Z.ZipType='S'
and Z.CityType='D'
Returns
ID StreetAddress CityName StateCode ZIPCode
1 701 MONROE STREET NW Russellville AL 35653
2 1825 HOLTVILLE ROAD Wetumpka AL 36092

Related

Pulling a section of a string between two characters in SQL, and the section of the string around the extracted section

I have a table that includes names and allows for a "nickname" for each name in parenthesis.
PersonName
John (Johnny) Hendricks
Zekeraya (Zeke) Smith
Ajamain Sterling (Aljo)
Beth ()) Jackson
I need to extract the Nickname, and return a column of nicknames and a column of full names (Full string without the nickname portion in parenthesis). I also need a condition for the nickname to be null if no nickname exists, and so that the nickname only returns letters. So far I have been able to figure out how to get the nickname out using Substring, but I can't figure out how to create a separate column for just the name.
Select SUBSTRING(PersonName, CHARINDEX('(', PersonName) +1,(((LEN(PersonName))-CHARINDEX(')',REVERSE(PersonName)))-CHARINDEX('(',PersonName)))
as NickName
from dbo.Person
Any help would be appreciated. I'm using MS SQL Server 2019. I'm pretty new at this, as you can tell.
Using your existing substring, one simple way is to use apply.
Assuming your last row is an example of a nickname that should be NULL, you can use an inline if to check its length - presumably a nickname must be longer than 1 character? Adjust this logic as required.
select PersonName, Iif(Len(nn)<2,null,nn) NickName, Trim(Replace(Replace(personName, Concat('(',nn,')') ,''),' ','')) FullName
from Person
cross apply (values(SUBSTRING(PersonName, CHARINDEX('(', PersonName) +1,(((LEN(PersonName))-CHARINDEX(')',REVERSE(PersonName)))-CHARINDEX('(',PersonName))) ))c(nn)
The following code will deal correctly with missing parenthesis or empty strings.
Note how the first CROSS APPLY feeds into the next
SELECT
PersonName,
NULLIF(NickName, ''),
FullName = ISNULL(REPLACE(personName, ' (' + NickName + ')', ''), PersonName)
FROM t
CROSS APPLY (VALUES(
NULLIF(CHARINDEX('(', PersonName), 0))
) v1(opening)
CROSS APPLY (VALUES(
SUBSTRING(
PersonName,
v1.opening + 1,
NULLIF(CHARINDEX(')', PersonName, v1.opening), 0) - v1.opening - 1
)
)) v2(NickName);
db<>fiddle

SQL Server : find and replace part of a specific part of string that appears more than once in a string

I am a small business owner who self-taught SQL Server to manage mailing data. This resource has helped me so many times in the past looking at other folks questions, however, this is the first time asking a question. Using SQL Server 2017.
In the address column I want to change abbreviations to spelled out words. For example, I want to change 'St' to 'Street'. I know how to do a basic find and replace in T-SQL, but what I am running into is that if 'St' is in the name of the actual street name, it is getting changed as well. For example, '123 Stripe St' becomes '123 Streetripe Street'. My desired output would be '123 Stripe Street'.
I am using the following
UPDATE Person
SET Addr = REPLACE(Addr, 'St', 'Street')
WHERE Addr like '%St'
Can someone please help me to replace just the abbreviated part of the address?
Any help is very much appreciated.
Normalizing addresses can be a slippery slope. You may be surprised on the variations of Blvd. This is why I suggest you take a peek at Address standardization within a database
That mentioned, here is a simple and easy to expand option
Example
Declare #YourTable table (id int,Addr varchar(150))
Insert Into #YourTable values
(1,'123 Stripe St')
,(2,'555 SW Main St, Providence, RI')
Update #YourTable
Set Addr = ltrim(rtrim(
replace(
replace(' '+Addr+' ',' St ',' Street ')
,' St, ',' Street, ')
))
Select * from #YourTable
Returns
id Addr
1 123 Stripe Street
2 555 SW Main Street, Providence, RI -- Notice middle St with a comma.
For this particular example, you can do:
UPDATE Person
SET Addr = LEFT(Addr, LEN(Addr) - 2) + 'Street'
WHERE Addr like '% St';
However, for more general patterns in the middle of the string, this will get more challenging. SQL Server is not the optimal tool for this type of string manipulation.

extract sub-string in T-SQL based on condition

I have address in sql column which also contain postcode i.e. as following format
10 westminister way Road, London (NW10 5NQ)
but not all record may have postcode which in case will be like
10 westminister way Road, London
I need to extract post from string which is working fine except following character throw error if postcode doesn't exist which i believe i need to use contain but not sure how to modify existing code to do so
select
,REVERSE(SUBSTRING(REVERSE([address]),2, CHARINDEX('(', REVERSE([address]))-2)) PostCode
,CHARINDEX('(', REVERSE([address]))-2 indexDetail
my question is how to use contain or if condition so
if(CHARINDEX('(', REVERSE([address])) = true then proceed with substring
else ignore record
Using IIF. This will grab everything in the parentheses, regardless of how long the postal code is. I'm not sure if they vary in the UK.
declare #table table ([address] varchar(256))
insert into #table
values
('10 westminister way Road, London (NW10 5NQ)'),
('10 westminister way Road, London')
select
[address],
PostCode = iif(charindex('(',[address]) > 1, substring([address],charindex('(',[address]),charindex(')',[address])),''),
PostalNoParan = iif(charindex('(',[address]) > 1, replace(replace(substring([address],charindex('(',[address]),charindex(')',[address])),'(',''),')',''),'')
from #table
SELECT
[address],
PostalCode = SUBSTRING([address], NULLIF(charindex('(',[address]),0), 256)
FROM #table;
If you need an empty string instead of NULL:
SELECT
[address],
PostalCode = COALESCE(SUBSTRING([address], NULLIF(charindex('(',[address]),0), 256),'')
FROM #table;
How about this?
select (case when address like '% (%)'
then left(right(address, 9), 8)
end) as postcode

Retrieve Second to Last Word in PostgreSQL

I am using PostgreSQL 9.5.1
I have an address field where I am trying to extract the street type (AVE, RD, ST, etc). Some of them are formatted like this: 5th AVE N or PEE DEE RD N
I have seen a few methods in PostgreSQL to count segments from the left based on spaces i.e. split_part(name, ' ', 3), but I can't seem to find any built-in functions or regular expression examples where I can count the characters from the right.
My idea for moving forward is something along these lines:
select case when regexp_replace(name, '^.* ', '') = 'N'
then *grab the second to last group of string values*
end as type;
Leaving aside the issue of robustness of this approach when applied to address data, you can extract the penultimate space-delimited substring in a string like this:
with a as (
select string_to_array('5th AVE N', ' ') as addr
)
select
addr[array_length(addr, 1)-1] as street
from
a;

Remove unwanted text from column values

I dont know how to do this. On my table I have descriptions mixed with description code. I need to remove the code description, just want the description. The description is just the first part without the acronym (capital letters at the end). I use SQL Server 2012
Example:
ColumnDescription
Chemistry Q
education E
psychology P
Sociology SOC
Documentation DOC
communication COM
Political Science CP
Pharmacy and Toxicology FT
Engineering Education (General) ING-G
If you are looking to simply strip the code that is at the end of each string, a way to do this is to identify the last space character in the string and then use SUBSTRING to extract everything before that character:
SELECT SUBSTRING(ColumnDescription, 0, LEN(ColumnDescription) - CHARINDEX(' ', REVERSE(ColumnDescription)) + 1) AS ColumnDescription
FROM Table
Note that I do not know what your table is called, so I called it Table.
This effectively reverses the column text (using REVERSE), finds the first occurrence of a space character (using CHARINDEX) and then subtracts this from the length of the text (using LEN).
Then a simple SUBSTRING is used to extract the left-most portion of the text, resulting in the output of:
ColumnDescription
-----------------
Chemistry
education
psychology
Sociology
Documentation
communication
Political Science
Pharmacy and Toxicology
Engineering Education (General)
Based on your sample data I would guess that your problem could be simplified to:
Split the string at the last space character in the string
In which case:
DECLARE #your_table table (
ColumnDescription varchar(100)
);
INSERT INTO #your_table (ColumnDescription)
VALUES ('Chemistry Q')
, ('education E')
, ('psychology P')
, ('Sociology SOC')
, ('Documentation DOC')
, ('communication COM')
, ('Political Science CP')
, ('Pharmacy and Toxicology FT')
, ('Engineering Education (General) ING-G');
SELECT *
, SubString(ColumnDescription, number_of_characters - last_space + 2, 100) As last_part
, SubString(ColumnDescription, 0, number_of_characters - last_space + 2) As first_part
FROM (
SELECT ColumnDescription
, Len(ColumnDescription) As number_of_characters
, Reverse(ColumnDescription) As reversed
, CharIndex(' ', Reverse(ColumnDescription)) As last_space
FROM #your_table
) As x;