i have a table with a column named CustomerName which stores a customer's full name(thats both names of a customer - first name, last name and any other names).
I want to redesign this table such that instead of just having CustomerName field, i should have CustomerFirstName, CustomerLastName and CustomerOtherNames(then customerName can be a concatenation of the 3 fields).
i already have customer records in the table with CustomerNames in format below
CustomerName
Tom John
Mary Joy
San Roy
now i need to run an update query that will set Tom, Mary and San as CustomerFirstName and set John, Joy and Roy as CustomerLastName for their respective rows but am stuck on this.
The following integrates the formulas suggested by Matt (Lima) into the actual UPDATE query; it also deals with various cases such as
when there is only a FirstName,
when there are leading or trailing spaces
when there's more than one space separating first name from last name
Alternatively, one may do away with the extra tests aimed at ensuring that there is a space, by adding a WHERE clause (WHERE CustomerName like ('% %').
-- Ensure no leading nor trailing spaces
UPDATE myTable
SET CustomerName = TRIM(CustomerName)
UPDATE myTable
SET FirstName = TRIM(LEFT(TRIM(CustomerName),
CASE CHARINDEX(' ', CustomerName)
WHEN 0 THEN LEN(CustomerName)
ELSE CHARINDEX(' ', CustomerName) -1
END)),
LastName = CASE CHARINDEX(' ', CustomerName)
WHEN 0 THEN ''
ELSE TRIM(SUBSTRING(CustomerName, CHARINDEX(' ', CustomerName) + 1, LEN(CustomerName))
END
You might be able to use something like:
SELECT SUBSTRING(CustomerName, 1, CHARINDEX(' ', CustomerName) - 1) AS [FirstName],
SUBSTRING(CustomerName, CHARINDEX(' ', CustomerName) + 1, LEN(CustomerName)) AS [LastName]
FROM yourTableName
I got this solution from: http://www.sql-server-helper.com/tips/split-name.aspx
Hope this helps.
Matt
Try something like:
SELECT SUBSTR(CustomerName, 1 ,INSTR(CustomerName, ' ', 1, 1)-1) as first_name, SUBSTR(CustomerName, INSTR(CustomerName,' ',1,1)) as last_name from yourTableName
(oracle)
Related
I have a need to retrieve a hierarchy of managers and the column which stores the manager names for a given person are formatted like this Smith, Mr. William (Bill). I want this output to simply be William Smith. So far I have put this together:
SELECT DISTINCT RIGHT(u.manager, LEN(u.manager)-(1+CHARINDEX(', ', u.manager))) + ' ' +
LEFT(u.manager, CHARINDEX(', ', u.manager) - 1) as ManagerName
FROM Users u
The current result from that query using my example above is Mr. William (Bill) Smith. This CHARINDEX and SUBSTRING stuff always gives me a lot of trouble so I am not really sure what the easiest way to do this is. This is also a one-off, so I am not sure a function would be useful here.
DEMO
SELECT
SUBSTRING(manager,0,CHARINDEX(',', manager)) as surname,
SUBSTRING(manager,CHARINDEX('. ', manager)+2, LEN(manager)-CHARINDEX(' (', manager)+1) as name,
CONCAT(SUBSTRING(manager,CHARINDEX('. ', manager)+2, LEN(manager)-CHARINDEX(' (', manager)+1),
' ',
SUBSTRING(manager,0,CHARINDEX(',', manager))) as 'name surname'
FROM
Users
Result:
+-------------+-----------+--------------+
| surname | name | name surname |
+-------------+-----------+--------------+
Smith William William Smith
I took your query and modified a little bit:
SELECT
---this is the tricky part: inner part finds the first instance of '(' parenthesis
--and substract it from the length of the first name and get only the left part of the first name by subtracting it
CONCAT (
LEFT(t.FirstName, LEN(t.FirstName) - (LEN(t.FirstName) - CHARINDEX('(', t.FirstName) + 1))
,t.LastName
)
FROM (
--basically separating your above syntax to two columns
SELECT RIGHT('Smith, Mr. William (Bill)', LEN('Smith, Mr. William (Bill)') - CHARINDEX('.', 'Smith, Mr. William (Bill)') - 1) AS FirstName
,LEFT('Smith, Mr. William (Bill)', CHARINDEX(', ', 'Smith, Mr. William (Bill)') - 1) AS LastName
) t
Here is the query that should work with your table name and column:
SELECT
---Use case when statement to determine if there are any instances of '(' in the first name
CONCAT (
CASE
WHEN CHARINDEX('(', t.FirstName) > 0
THEN LEFT(t.FirstName, LEN(t.FirstName) - (LEN(t.FirstName) - CHARINDEX('(', t.FirstName) + 1))
ELSE t.FirstName + ' '
END
,t.LastName
)
FROM (
SELECT
RIGHT(u.manager, LEN(u.manager) - CHARINDEX('.', u.manager) - 1) AS FirstName
,LEFT(u.manager, CHARINDEX(', ', u.manager) - 1) AS LastName from Users u
) t
SELECT RIGHT(NameStripped, LEN(NameStripped) - (1 + CHARINDEX(', ', NameStripped))) + ' ' + LEFT(NameStripped, CHARINDEX(', ', NameStripped) - 1) AS ManagerName --Your original code
FROM (
SELECT replace(replace(
LEFT(u.manager, CHARINDEX('(', u.manager) - 2) --Get rid of nickname
, 'Mr. ', ''), 'Ms.', '') AS NameStripped --Get rid of Mr/Ms
from MyTable u) a
This should work - I used the code you posted, but added a subquery to remove the nicknames and prefixes.
Note that you may need to adjust this if a) you have more prefix options than this (in which case you could add additional replaces) and/or b) not everyone in your database has a nickname (in which case you'll want to wrap that part in a case statement, most likely).
I have a column as FullName containg FirstName, MiddleName, LastName in it.
For example:
FullName: Marilyn Kean Kirkland
I want to have 3 separate columns for FirstName, MiddleName and LastName from the FullName by taking a substring from it.
I am pulling the FirstName by using the code:
substring(c.LegalName, 1, CHARINDEX(' ', c.LegalName)) as 'First Name'
I am wondering how can I pull just the middle name which comes after first space and before second space?
Also, I want to pull the last name which comes after the second space?
SQL Server doesn't have very good string manipulation functions. This is easier with subqueries:
select firstname,
stuff(reverse(stuff(reverse(legalname), 1, len(lastname) + 1, '')),
1, len(firstname) + 1, '')
from (select legalname,
left(legalname, charindex(' ', legalname) - 1) as firstname,
right(legalname, charindex(' ', reverse(legalname)) - 1) as lastname
. . .
) c
However, I would be very careful, because not all people have three part names. And others have suffixes (JR, SR) and other complications.
You can try something like this.
;WITH c AS
(
SELECT 'Marilyn Kean Kirkland' AS legalname
UNION ALL SELECT 'J Smith' AS legalname
)
SELECT
SUBSTRING(legalname,1,space1) firstname,
SUBSTRING(legalname,space1,space2 - space1 + 1) middlename,
SUBSTRING(legalname,space2 + 1,totallength - space2) lastname
FROM
(
SELECT
legalname,
CHARINDEX(' ',legalname) space1,
LEN(legalname) - CHARINDEX(' ',REVERSE(legalname)) space2,
LEN(legalname) as totallength
FROM c
)c
GO
As noted above by other users as well,these scripts will work with user that only have 3 part or 2 part names.
I have a column which is named "Firstname" and contains
Firstname Lastname
and I want to create another column called Lastname and cut the Lastname from the "Firstaname" column and paste it on the "Lastname" column, for multiple rows.
before
Firstname
---------
Bob Weller
after
Firstname | Lastname
----------|---------
Bob | Weller
edit:
after Lastname there might be a number or other strings such as ( ) etc.. which should go to the Lastname column
This query splits it into FirstName and LastName at the first space.
SELECT FirstNameLastName,
substring(FirstNameLastName, 0, charindex(' ', FirstNameLastName) -1) as FirstName,
substring(FirstNameLastName, charindex(' ', FirstNameLastName) -1,len(FirstNameLastName)) as LastName
from [Table]
To modify your table and move the old column into new columns, you can do the following:
Alter your table first to create your new columns:
Alter Table [TableName]
Add FirstName varchar(50),
LastName Varchar(50)
Then use an update statement to move the values into it
Update Table [TableName]
Set FirstName = substring(FirstNameLastName, 0, charindex(' ', FirstNameLastName)-1),
LastName = substring(FirstNameLastName, charindex(' ', FirstNameLastName)-1,len(FirstNameLastName))
This should move the values from the old column into the two new columns.
The following is similar to the accepted answer, except:
- It deals with strings that don't contain a space
- It uses OUTER APPLY to avoid re-writing the CHARINDEX multiple times
- It doesn't include the space as the last character of the new first name
- It doesn't include the space as the first character of the new last name
SELECT
*,
CASE
WHEN lookup.first_space = 0 THEN ''
ELSE SUBSTRING(yourTable.firstName, 1, lookup.first_space - 1)
END AS new_firstName,
CASE
WHEN lookup.first_space = 0 THEN yourTable.firstName
ELSE SUBSTRING(yourTable.firstName, lookup.first_space + 1, 9999)
END AS new_lastName
FROM
yourTable
OUTER APPLY
(SELECT CHARINDEX(' ', yourTable.firstName, 0) AS first_space) AS lookup
If you want then split into 2 columns not rows then something like this should do:
SELECT
SUBSTRING(WholeName, 1, CHARINDEX(' ', WholeName) - 1) AS Firstname,
SUBSTRING(WholeName, CHARINDEX(' ', WholeName) + 1, len(FirstName)) AS LastName
FROM MyTable
NOTE: This is assuming that EVERY record has a space between first and last names.
I have a column name. There are entries such-as:
Smith, John
Smith, Joe
One whole entry
I need them separated into two columns as this:
LastName | FirstName
---------------------------
Smith | John
Smith | Joe
One whole entry |
I'm using this query:
SELECT left(name, CHARINDEX(', ', name)) as LastName FROM LookUps
I've tried the following above, but it's displaying the following comma (e.g. Smith,). I need it to remove this following comma, but also display the full information for those entries without a comma.
Any help would be appreciated. Thanks..
select
case when charindex(',',name) > 0
then left(name, charindex(',',name)-1 )
else name end,
case when charindex(',',name) > 0
then ltrim(substring(name, charindex(',',name)+1, len(name) ))
else null end
from yourtable
Another way;
select
left(name, charindex(',', name + ',', 1) - 1) as lastname,
ltrim(substring(name, charindex(',', name + ',', 1) + 1, len(name))) as firstname
I have a SQL Table with a column called FullName which contains, for example, "John Smith".
How can order the data by the last name that appears in the FullName column?
For a long name like "Laurence John Fishburne", I would like to order the data by the word "Fishburne".
Thus, names are stored in the order
First Name
Middle Names
Last Name
I am using Microsoft SQL Server 2005.
I would do something like:
SELECT FullName
FROM TABLE
ORDER BY REVERSE(SUBSTRING(REVERSE(FullName), 0, CHARINDEX(' ', REVERSE(FullName))))
Instead of calculating what the last name is each time you want to run the query, you can have a computed column that persists the actual value into a column that can be used as you would any other column.
ALTER TABLE Customer
ADD LastName AS
RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1) PERSISTED
This Adds the column LastName to your Customer table, uses the function specified to calculate the value of the last name, and stores it onto the physical table. The keyword PERSISTED at the end is required for the value to be saved to the disk, else it will be computed each time a query is run.
Edit:
To deal with values with no spaces:
ALTER TABLE Customer
ADD LastName AS
case when CHARINDEX(' ', REVERSE(FullName)) > 0
then RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1)
else
FullName
end
PERSISTED
Though you can fiddle with this function as you will to determine what happens in this case. My point is to show that case statements can be used. You may also want to cast all output paths to the same type to avoid type mismatches.
try this, it uses the minimal number of functions to find the last space in the FullName string, which should help performance:
DECLARE #YourTable table (FullNamevarchar(30))
INSERT #YourTable VALUES ('Harry Smith');
INSERT #YourTable VALUES ('John Davis');
INSERT #YourTable VALUES ('Allision Thomas Williams');
SELECT
FullName
,RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1) AS SortBy
FROM #YourTable
ORDER BY RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1)
OUTPUT:
FullName SortBy
------------------------------ ------------------------------
John Davis Davis
Harry Smith Smith
Allision Thomas Williams Williams
(3 row(s) affected)
For the best performance and most accurate sort, you need to split out the name into Firstname, MiddleName, and LastName fields. Only the user entering the data can really understand what portion of FullName is the last name.
Query
SELECT stringrowname FROM tablename
ORDER BY SUBSTRING_INDEX((stringrowname)," ",-1);
It will return the strings order by last word.
create table foo(fullname varchar(100))
go
insert into foo values ('Harry Smith');
insert into foo values ('John Davis');
insert into foo values ('Allision Thomas Williams');
SELECT fullname
, REVERSE(left(REVERSE(fullname), charindex(' ',REVERSE(fullname))-1))
FROM foo
ORDER BY REVERSE(left(REVERSE(fullname), charindex(' ',REVERSE(fullname))-1))
Output:
fullname (No column name)
John Davis Davis
Harry Smith Smith
Allision Thomas Williams Williams
When in doubt, do it yourself:
Select
*
From
Users
Order By
LTrim(Reverse(Left(Reverse(FullName), CharIndex(' ', Reverse(FullName))))) Asc,
FullName Asc -- Fall-over for when there isn't a last name
This will do the trick:
create table #tmpTable
(
ID int identity(1,1) primary key,
FullName varchar(100) not null
);
insert into #tmpTable(FullName) values('Big John Sansom');
insert into #tmpTable(FullName) values('Mike Douglas Reid');
insert into #tmpTable(FullName) values('First Second Last');
insert into #tmpTable(FullName) values('JustOneTokenForName');
select
FullName,
LastName = case
when CHARINDEX(FullName,' ') = 0 THEN FullName
else RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1)
end
from #tmpTable
order by LastName
drop table #tmpTable
It really depends on how names are stored. Assuming "Last, First Middle" you could do something like
order by substring(0, charindex(',', FullName))
You may have to fiddle with it a little, but I believe that should work.