Trim extra white space within column - sql

I have the following select that is converting a name from Lastname, Firstname format into Firstname Lastname format. It seems to be adding extra white space between the first name and the last name
SELECT substring(D.NAME, charindex(',', replace(D.NAME, ' ', '')) + 1, len(D.NAME))
+ ' '
+ left(D.NAME, charindex(',', D.NAME) -1) AS First_Last
FROM TEST_TABLE D
Here are a few examples of the output I'm getting now:
Johnnyyy Smithsonnn
Kimmey Test1
Denise Stuffing
Desired Format (single space between first and last name):
Johnnyyy Smithsonnn
Kimmey Test1
Denise Stuffing

I tend to like this technique. In this example we use a rare replacement pattern of †‡, but you can use <> and ><
Note: The outer ltrim(rtrim( ... )) is optional, I keep it as a "just in case".
Example
Select NewValue = ltrim(rtrim(replace(replace(replace([Name],' ','†‡'),'‡†',''),'†‡',' ')))
From YourTable
Returns
NewValue
Johnnyyy Smithsonnn
Kimmey Test1
Denise Stuffing

Maybe there are names with or without , or with or without spaces after the ,, or other inconsistencies.
Anyway you can use ltrim(rtrim()) before concatenating:
select
case
when d.name like '%,%' then
ltrim(rtrim(substring(d.name, charindex(',', name) + 1, len(d.name))))
+ ' ' +
ltrim(rtrim(left(D.NAME, charindex(',', d.name) -1)))
when d.name like '% %' then
ltrim(rtrim(substring(d.name, charindex(' ', name) + 1, len(d.name))))
+ ' ' +
ltrim(rtrim(left(D.NAME, charindex(' ', d.name) -1)))
else ltrim(rtrim(d.name))
end AS First_Last

Try:
select ltrim(rtrim(left(D.NAME, charindex(',', D.NAME, 0) - 1)))
+ ' '
+ ltrim(rtrim(right(D.NAME, len(D.NAME) - charindex(',', D.NAME, 0))))
from TEST_TABLE D
This worked on some test data I used below:
insert into #Test ([Name]) values ('Johnnyyy, Smithsonnn')
insert into #Test ([Name]) values ('Kimmey, Test1')
insert into #Test ([Name]) values ('Denise, Stuffing')
Which gives the intended result:
Johnnyyy Smithsonnn
Kimmey Test1
Denise Stuffing

I think you intend to do the replace of spaces after extracting the name. So:
SELECT (replace(left(D.NAME, charindex(',', D.NAME + ',') + 1), ' ', '') +
' ' +
left(D.NAME, charindex(',', D.NAME + ',') - 1)
) AS First_Last
FROM TEST_TABLE D;
This also adds a comma for the charindex() so the comma is optional.

Related

How to get middle portion from Sql server table data?

I am trying to get First name from employee table, in employee table full_name is like this: Dow, Mike P.
I tried with to get first name using below syntax but it comes with Middle initial - how to remove middle initial from first name if any. because not all name contain middle initial value.
-- query--
select Employee_First_Name as full_name,
SUBSTRING(
Employee_First_Name,
CHARINDEX(',', Employee_First_Name) + 1,
len(Employee_First_Name)) AS FirstName
---> remove middle initial from right side from employee
-- result
Full_name Firstname Dow,Mike P. Mike P.
--few example for Full_name data---
smith,joe j. --->joe (need result as)
smith,alan ---->alan (need result as)
Instead of specifying the len you need to use charindex again, but specify that you want the second occurrence of a space.
select Employee_First_Name as full_name,
SUBSTRING(
Employee_First_Name,
CHARINDEX(',', Employee_First_Name) + 1,
CHARINDEX(' ', Employee_First_Name, 2)) AS FirstName
One thing to note, the second charindex can return 0 if there is no second occurence. In that case, you would want to use something like the following:
select Employee_First_Name as full_name,
SUBSTRING(
Employee_First_Name,
CHARINDEX(',', Employee_First_Name) + 1,
IIF(CHARINDEX(' ', Employee_First_Name, 2) = 0, Len(Employee_First_name), CHARINDEX(' ', Employee_First_Name, 2))) AS FirstName
This removes the portion before the comma.. then uses that string and removes everything after space.
WITH cte AS (
SELECT *
FROM (VALUES('smith,joe j.'),('smith,alan'),('joe smith')) t(fullname)
)
SELECT
SUBSTRING(
LTRIM(SUBSTRING(fullname,CHARINDEX(',',fullname) + 1,LEN(fullname))),
0,
COALESCE(NULLIF(CHARINDEX(' ',LTRIM(SUBSTRING(fullname,CHARINDEX(',',fullname) + 1,LEN(fullname)))),0),LEN(fullname)))
FROM cte
output
------
joe
alan
joe
To be honest, this is most easily expressed using multiple levels of logic. One way is using outer apply:
select ttt.firstname
from t outer apply
(select substring(t.full_name, charindex(', ', t.full_name) + 2, len(t.full_name) as firstmi
) tt outer apply
(select (case when tt.firstmi like '% %'
then left(tt.firstmi, charindex(' ', tt.firstmi)
else tt.firstmi
end) as firstname
) as ttt
If you want to put this all in one complicated statement, I would suggest a computed column:
alter table t
add firstname as (stuff((case when full_name like '%, % %.',
then left(full_name,
charindex(' ', full_name, charindex(', ', full_name) + 2)
)
else full_name
end),
1,
charindex(', ', full_name) + 2,
'')
If format of this full_name field is the same for all rows, you may utilize power of SQL FTS word breaker for this task:
SELECT N'Dow, Mike P.' AS full_name INTO #t
SELECT display_term FROM #t
CROSS APPLY sys.dm_fts_parser(N'"' + full_name + N'"', 1033, NULL, 1) p
WHERE occurrence = 2
DROP TABLE #t

SQl string split (parse) on space where some field values have no space

I've been trying to split a string value in my query to return the first part of a two part postcode in a new column. Some values have only the first part, and some have both. After a bit of searching I found this code:
SELECT
TblPLSSU.PLSSUPostcode
,SUBSTRING(TblPLSSU.PLSSUPostcode, 1, CHARINDEX(' ', TblPLSSU.PLSSUPostcode)) AS PCode
FROM
TblPostcodes
This happily splits the values that have two parts to the postcode but it seems to be ignoring the single part post codes.
For example, values for TblPLSSU.PLSSUPostcode might be:
EH1 1AB
EH2
I want to return the values
EH1
EH2
But with the code above I am only getting EH1
Thanks
Eils
Use case to pick up post codes as-is when they don't have a space separated value.
SELECT
PLSSUPostcode
,case when CHARINDEX(' ', PLSSUPostcode) > 0
then SUBSTRING(PLSSUPostcode, 1, CHARINDEX(' ', PLSSUPostcode))
else PLSSUPostcode end AS PCode
FROM
TblPostcodes
Use case as well:
SELECT TblPLSSU.PLSSUPostcode,
(CASE WHEN TblPLSSU.PLSSUPostcode LIKE '% %'
THEN SUBSTRING(TblPLSSU.PLSSUPostcode, 1, CHARINDEX(' ', TblPLSSU.PLSSUPostcode))
END) AS PCode
FROM . . .
A little trick with STUFF function. This works because of CHARINDEX returns index of the first occurrence. So you are just adding space to strings and replacing all symbols from first occurrence till the end with empty string:
DECLARE #t TABLE(v VARCHAR(20))
INSERT INTO #t VALUES('EH1 1AB'), ('EH2')
SELECT STUFF(v + ' ', CHARINDEX(' ', v + ' '), LEN(v), '')
FROM #t
Another version:
SELECT SUBSTRING(v + ' ', 1, CHARINDEX(' ', v + ' ') - 1)
FROM #t
Output:
EH1
EH2

comma separated column values

I need to take the values from 3 columns and group them into 1 column as comma separated:
2014-01-01,2014-01-29
The problem is that one or more columns can be NULL and therefore it messes up the commas as such:
2014-01-01,,2014-01-29
This is how I have it coded (the case statement basically just strips out a comma if it's the last character in the string.
I need to add some logic so that it takes into account NULLs but I'm having a hard time coming up with it.
CASE WHEN RIGHT(ISNULL(d.FirstGapDate + ',', '') + ISNULL(d.PayrollGapDate + ',', '') + d.LastGapDate, 1) = ','
THEN LEFT(ISNULL(d.FirstGapDate + ',', '') + ISNULL(d.PayrollGapDate + ',', '') + d.LastGapDate, LEN(ISNULL(d.FirstGapDate + ',', '') + ISNULL(d.PayrollGapDate + ',', '') + d.LastGapDate) - 1)
ELSE ISNULL(d.FirstGapDate + ',', '') + ISNULL(d.PayrollGapDate + ',', '') + d.LastGapDate
END AS AlLGapDatesFormatted
EDIT -
I need to group the highlighted (notice that PayrollGapDate is ''):
And this is what I'm getting:
And this is the code I implemented:
try using this technique:
SET CONCAT_NULL_YIELDS_NULL ON --<<<make sure concatenations with NULL result in NULL
DECLARE #C1 varchar(10)='AAA'
,#C2 varchar(10)='BBB'
,#C3 varchar(10)=null
,#C4 varchar(10)='DDD'
SELECT STUFF( ISNULL(', '+#C1,'')
+ISNULL(', '+#C2,'')
+ISNULL(', '+#C3,'')
+ISNULL(', '+#C4,'')
,1,2,''
)
output:
-----------------------------------------------
AAA, BBB, DDD
(1 row(s) affected)
You let the ', '+#C3 result in NULL, which the ISNULL(***,'') converts to empty string. The STUFF(***,1,2,'') removes the leading comma and space.
try:
SELECT STUFF( ISNULL(', '+d.FirstGapDate,'')
+ISNULL(', '+d.PayrollGapDate,'')
+ISNULL(', '+d.LastGapDate,'')
,1,2,''
)
FROM ...
WHERE...
You can apply something like this above your expression to replace many commas with one comma:
declare #s varchar(100) = 'ABC,,,,DEF'
select replace(replace(replace(#s, ',', '[]'), '][', ''), '[]', ',')

Extracting first word from a string in SQL, where the string is a single word

I am able to extract the first word from a string, using ANSI SQL, like this:
SELECT SUBSTRING(name FROM 1 FOR POSITION(' ' IN name)) AS first_name
However, if the original string is only one word long (ie, if there is no space), it returns an empty substring.
How can the above query be adapted to solve this problem?
Thanks in advance.
I'm sure there is a cleaner way to do it, but this works.
DECLARE #tbl TABLE (i varchar(100));
INSERT INTO #tbl ( i )
VALUES ('hello'), ('hello space here');
SELECT *,
SUBSTRING(i, 0, CASE CHARINDEX(' ', i)
WHEN 0 THEN LEN(i) + 1
ELSE CHARINDEX(' ', i)
END)
FROM #tbl
Simply but messy solution - add a space on the end:
SELECT SUBSTRING((name || ' ') FROM 1 FOR POSITION(' ' IN (name || ' '))) AS first_name
Use a conditional if statement.
For a MySQL/SQL Server answer:
SELECT IF(INSTR(name, ' ') >0, LEFT(name, INSTR(name, ' ') - 1), name) AS firstname
For Oracle:
SELECT IF(INSTRB(name, ' ', 1, 1) >0, SUBSTR(name, 1, INSTRB(name, ' ', 1, 1) - 1), name) AS firstname
I personally prefer the Regexp query for this, but below query also works.
You basically append a space at the end of the string and search for the position of the space using INSTR.
ORACLE:
select substr(Var1, 0,INSTR(Var1||' ',' ')) from table-name;
Replace Var1 with the column-name or string you are evaluating.
Put Column Name in place of #foo
DECLARE #Foo VARCHAR(50) = 'One Two Three'
SELECT
CASE
--For One Word
WHEN CHARINDEX(' ', #Foo, 1) = 0 THEN #Foo
--For multi word
ELSE SUBSTRING(#Foo, 1, CHARINDEX(' ', #Foo, 1) - 1)
END
DECLARE #test VARCHAR(50) = 'One Two Three'
SELECT SUBSTRING(LTRIM(#test),1,(CHARINDEX(' ',LTRIM(#test) + ' ')-1))
you can use this to get the first word of a string.initcap
will get you the first letter capital.
SELECT SUBSTR(column_1, 1, INSTR(column_1, ' ', 1,1) ) FROM table_name WHERE column_1= initcap('your string');

How do I split and comma-delimit names?

I have this column
NAME
John Stephenson
James Martin
Anna Corelia
How I can select this column to this?
NAME
Stephenson, John
Martin, James
Corelia, Anna
One way
;with test(name) as (
select 'John Stephenson' union all
select 'James Martin' union all
select 'Anna J. Corelia' union all
select 'BOBBYTABLES'
)
select
case when charindex(' ', name) = 0 then name
else right(name, charindex(' ', reverse(name)) - 1) + ', ' + substring(name, 1, len(name) - charindex(' ', reverse(name))) end
from test
(No column name)
Stephenson, John
Martin, James
Corelia, Anna J.
BOBBYTABLES
Your question has nothing to do with TRIM() function. Probably you are trying to get something like below using LEFT() and RIGHT() function of SQL Server and concatanating them with ,
select right('John Stephenson',(len('John Stephenson')-charindex(' ','John Stephenson')))
+ ', ' + left('John Stephenson',(charindex(' ','John Stephenson') - 1))
which will result in
Stephenson, John
Here is a solution including how I got the final output column.
This will handle three part names, like "Rip Van Winkle", also names with no white space and will strip (trim) any leading/trailing white space from the names.
DECLARE #NAMES TABLE (NAME NVARCHAR(MAX))
INSERT INTO #NAMES (NAME) VALUES ('John Stephenson'),('James Martin'),('Anna Corelia'),('Rip Van Winkle'),('Sally')
SELECT *,
CHARINDEX(' ',LTRIM(RTRIM(NAME))) [SpaceLocation],
CASE WHEN CHARINDEX(' ',LTRIM(RTRIM(NAME)))>0 THEN RIGHT(LTRIM(RTRIM(NAME)), LEN(LTRIM(RTRIM(NAME)))-CHARINDEX(' ',LTRIM(RTRIM(NAME)))) END [LastName],
CASE WHEN CHARINDEX(' ',LTRIM(RTRIM(NAME)))>0 THEN LEFT(LTRIM(RTRIM(NAME)),CHARINDEX(' ',LTRIM(RTRIM(LTRIM(RTRIM(NAME)))))-1) END [FirstName],
CASE WHEN CHARINDEX(' ',LTRIM(RTRIM(NAME)))>0 THEN RIGHT(LTRIM(RTRIM(NAME)), LEN(LTRIM(RTRIM(NAME)))-CHARINDEX(' ',LTRIM(RTRIM(NAME)))) + ', ' +LEFT(LTRIM(RTRIM(NAME)),CHARINDEX(' ',LTRIM(RTRIM(NAME)))-1) ELSE LTRIM(RTRIM(NAME)) END [FinalOutput]
FROM #NAMES
SELECT substring(NAME+', '+NAME,charindex(' ',NAME)+1,len(NAME)+1) FROM MyTable
This also turns "Rip Van Winkle" into "Van Winkle, Rip"
SQL Fiddle Demo
There is no a single trim function but you can
select ltrim(rtrim(colname)) from tablename
which will TRIM both sides.
but what you need is:
declare #name varchar(300) ='Stephenson John';
Select
Substring(#name, 1,Charindex(' ', #name)-1) +
', ' +
Substring(#name, Charindex(' ', #name)+1, LEN(#name))
as name
Sorry I miss post