parse lastname, firstname and truncate and caps - sql

I have a field stores customer name all in one column: John, Dao. Names are stored as Lastname, FirstName.
What I need to do is list last name in CAPS, truncated at 10 characters, followed by first initial of first name (first initial Caps Letter). For example John, Dao needs to be displayed as JOHN D.

Try something like this...
DECLARE #FullName varchar(50) = 'Smithxxxxxxxxx, John';
SELECT UPPER(SUBSTRING(SUBSTRING(#FullName, 1, CHARINDEX(',', #FullName)-1), 1, 10) ) as LastName
, UPPER( LTRIM( SUBSTRING(#FullName, CHARINDEX(',', #FullName) +1, 2))) as FirstName

--Example 1
DECLARE #FullName VARCHAR(50) = 'Smithxxxxxxxxx, John';
SELECT UPPER(LEFT(#FullName,
CHARINDEX(',', #FullName) - 1)) AS LastName ,
UPPER(LEFT(REPLACE(RIGHT(#FullName,
LEN(#FullName)
- CHARINDEX(',',
#FullName) - 1),
', ', ''), 1)) AS FirstName
-------------------------------------
--Example 2
DECLARE #FullName VARCHAR(50) = 'Smithxxxxxxxxx, John';
SELECT UPPER(LEFT(#FullName,
CHARINDEX(',', #FullName) - 1)) AS LastName ,
UPPER(LEFT(REPLACE(REVERSE(LEFT(REVERSE(#FullName),
CHARINDEX(',',
REVERSE(#FullName)))),
', ', ''), 1)) AS FirstName

Here's an example in SQLite:
sqlite> create table customer(lastname string, firstname string);
sqlite> insert into customer values("VerylongNameIndeed", "alex");
sqlite> SELECT UPPER(SUBSTR(lastname, 1, 10)), UPPER(SUBSTR(firstname, 1, 1)) FROM customer;
The result: VERYLONGNA|A
EDIT: I've just realised that the names are both stored as a single column in the question, so here's an amended version of the above:
sqlite> create table customer(name string);
sqlite> insert into customer values("john, dao");
sqlite> insert into customer values("VeryLongName, alex");
sqlite> SELECT UPPER(SUBSTR(name, 1, MIN(10, INSTR(name, ",")-1))), UPPER(SUBSTR(name, INSTR(name, ",")+2, 1)) FROM customer;
The result:
JOHN|D
VERYLONGNA|A

Related

first letters in firstname and lastname uppercase

Assuming I have a table full of names.
firstname.lastname in a single cell.
How can I seperate these into "Firstname Lastname", with uppercase for the first letters? Using TSQL
Sample:
mike.mikeson -> Mike Mikeson
katy.lumberjack -> Katy Lumberjack
One of those times we can use the ParseName function for our benefit ;-)
SELECT original_value
, forename
, surname
, Upper(SubString(forename, 1, 1)) + Lower(Substring(forename, 2, 8000)) AS formatted_forename
, Upper(SubString(surname , 1, 1)) + Lower(Substring(surname , 2, 8000)) AS formatted_surname
FROM (
SELECT name AS original_value
, ParseName(name, 2) AS forename
, ParseName(name, 1) AS surname
FROM (
VALUES ('mike.mikeson')
, ('katy.lumberjack')
) AS users (name)
) AS step1
The below will answer you question as is but as comments have pointed out, you may need to also take into account names that have more than one uppercase letter in either part, such as Mary-Anne McDonald, or those that simply don't conform to your convention.
declare #a table (Name nvarchar(50))
insert into #a values
('fred.bloggs')
,('john.doe')
,('alan.smith')
select Name
,upper(left(Name,1))
+ substring(Name,2,charindex('.',Name,1)-2)
+ ' '
+ upper(substring(Name,charindex('.',Name,1)+1,1))
+ right(Name,len(Name) - charindex('.',Name,1)-1)
as FormattedName
from #a
You can try using concat and substring for this as below
declare #name varchar(50) = 'firstname.lastname'
select case when charindex('.',#name) > 0 then concat(upper(left(#name,1)), substring(#name,2,charindex('.',#name)-2), ' ', upper(substring(#name,charindex('.',#name)+1,1)), substring(#name,charindex('.',#name)+2, len(#name)))
else concat(upper(left(#name,1)), substring(#name,2,len(#name))) end

How to Specify Trim Chars in SQL TRIM

I'm having a table Employee, in that some values are started with ", ". So, I need to remove the comma and white-space at the beginning of the name at the time of SELECT query using LTRIM() - SQL-Server.
My Table : Employee
CREATE TABLE Employee
(
PersonID int,
ContactName varchar(255),
Address varchar(255),
City varchar(255)
);
INSERT INTO Employee(PersonID, ContactName, Address, City)
VALUES ('1001',', B. Bala','21, Car Street','Bangalore');
SELECT PersonID, ContactName, Address, City FROM Employee
Here the ContactName Column has a value ", B. Bala". I need to remove the comma and white-space at the beginning of the name.
Alas, SQL Server does not support the ANSI standard functionality of specifying the characters for LTRIM().
In this case, you can use:
(case when ContactName like ', %' then stuff(ContactName, 1, 2, '')
else ContactName
end)
You could potentially use PATINDEX() in order to get this done.
DECLARE #Text VARCHAR(50) = ', Well Crap';
SELECT STUFF(#Text, 1, PATINDEX('%[A-z]%', #Text) - 1, '');
This would output Well Crap. PATINDEX() will find first letter in your word and cut everything before it.
It works fine even if there's no leading rubbish:
DECLARE #Text VARCHAR(50) = 'Mister Roboto';
SELECT STUFF(#Text, 1, PATINDEX('%[A-z]%', #Text) - 1, '');
This outputs Mister Roboto
If there are no valid characters, let's say ContactName is , 9132124, :::, this would output NULL, if you'd like to get blank result, you can use COALESCE():
DECLARE #Text VARCHAR(50) = ', 9132124, :::';
SELECT COALESCE(STUFF(#Text, 1, PATINDEX('%[A-z]%', #Text) - 1, ''), '');
This will output an empty string.
You could also use REPLACE.....
eg.
REPLACE( ' ,Your String with space comma', ' ,', '')
UPDATE dbo.Employee
SET
dbo.Employee.ContactName = replace(LEFT(ContactName, 2),', ','')
+ SUBSTRING (ContactName, 3, len(contactname))
where LEFT(ContactName, 2)=', '
This will only update where first two character contains ', '

How to find more than 1 uppercase character

I'm running a series of SQL queries to find data that needs cleaning up. One of them I want to do is look for:
2 or more uppercase letters in a row
starting with a lowercase letter
space then a lowercase letter
For example my name should be "John Doe". I would want it to find "JOhn Doe" or "JOHN DOE" or "John doe", but I would not want it to find "John Doe" since that is formatted correctly.
I am using SQL Server 2008.
The key is to use a case-sensitive collation, i.e. Latin1_General_BIN*. You can then use a query with a LIKE expression like the following (SQL Fiddle demo):
select *
from foo
where name like '%[A-Z][A-Z]%' collate Latin1_General_BIN --two uppercase in a row
or name like '% [a-z]%' collate Latin1_General_BIN --space then lowercase
*As per How do I perform a case-sensitive search using LIKE?, apparently there is a "bug" in the Latin1_General_CS_AS collation where ranges like [A-Z] fail to be case sensitive. The solution is to use Latin1_General_BIN.
First, I think you should make a function that returns a proper name (sounds like you need one anyway). See here under the heading "Proper Casing a Persons Name". Then find the ones that don't match.
SELECT Id, Name, dbo.ProperCase(Name)
FROM MyTable
WHERE Name <> dbo.PoperCase(Name) collate Latin1_General_BIN
This will help you clean up the data and tweak the function to what you need.
You can use a regular expression. I'm not a SQL Server whiz, but you want to use RegexMatch. Something like this:
select columnName
from tableName
where dbo.RegexMatch( columnName,
N'[A-Z]\W[A-Z]' ) = 1
If your goal is to update your column to capitalize the first character of each word (in your case firstName and lastName) , you can use the following query.
Create a sample table with data
Declare #t table (Id int IDENTITY(1,1),Name varchar(50))
insert into #t (name)values ('john doe'),('lohn foe'),('tohnytty noe'),('gohnsdf fgedsfsdf')
Update query
UPDATE #t
SET name = UPPER(LEFT(SUBSTRING(Name, 1, CHARINDEX(' ', Name) - 1), 1)) + RIGHT(SUBSTRING(Name, 1, CHARINDEX(' ', Name) - 1), LEN(SUBSTRING(Name, 1, CHARINDEX(' ', Name) - 1)) - 1) +
' ' +
UPPER(LEFT(SUBSTRING(Name, CHARINDEX(' ', Name) + 1, 8000), 1)) + RIGHT(SUBSTRING(Name, CHARINDEX(' ', Name) + 1, 8000), LEN(SUBSTRING(Name, CHARINDEX(' ', Name) + 1, 8000)) - 1)
FROM #t
Output
SELECT * FROM #t
Id Name
1 John Doe
2 Lohn Foe
3 Tohnytty Noe
4 Gohnsdf Fgedsfsdf
I use this way:
;WITH yourTable AS(
SELECT 'John Doe' As name
UNION ALL SELECT 'JOhn Doe'
UNION ALL SELECT 'JOHN DOE'
UNION ALL SELECT 'John doe'
UNION ALL SELECT 'John DoE'
UNION ALL SELECT 'john Doe'
UNION ALL SELECT 'jOhn dOe'
UNION ALL SELECT 'jOHN dOE'
UNION ALL SELECT 'john doe'
)
SELECT name
FROM (
SELECT name,
LOWER(PARSENAME(REPLACE(name, ' ', '.'), 1)) part2,
LOWER(PARSENAME(REPLACE(name, ' ', '.'), 2)) part1
FROM yourTable) t
WHERE name COLLATE Latin1_General_BIN = UPPER(LEFT(part1,1)) + RIGHT(part1, LEN(part1) -1) +
' ' + UPPER(LEFT(part2,1)) + RIGHT(part2, LEN(part2) -1)
Note:
This will be good for just two parted names for more, it should improved.

Splitting value of a varchar column into two columns

If I have a column in which strings vary in length but they ALL have a slash \ within,
how can I SELECT to have one column display everything BEFORE the \ and another column displaying everything AFTER the \?
name column1 column2
DB5697\DEV DB5697 DEV
I have seen CHARINDEX and REVERSE on MSDN but haven't been able to put together a soltuion.
How can I best split a varchar/string column value into 2 columns in a result set in TSQL ?
what about using PARSENAME function in a tricky way?
USE tempdb;
GO
CREATE TABLE #names
(
id int NOT NULL PRIMARY KEY CLUSTERED
, name varchar(30) NOT NULL
);
GO
INSERT INTO #names (id, name)
VALUES
(1, 'DB5697\DEV'),
(2, 'DB5800\STG'),
(3, 'DB5900\PRD');
GO
SELECT
name
, PARSENAME(REPLACE(name, '\', '.'), 2) AS [Server]
, PARSENAME(REPLACE(name, '\', '.'), 1) AS [Instance]
FROM
#names;
GO
DROP TABLE #names;
GO
The PARSENAME function accepts 2 parameters and gets the name part of a fully qualified name. The second parameter is the part name enumerator.
Value 2 is for SCHEMA and 1 is for OBJECT.
So, with the REPLACE function the "\" char is replaced by "." in order to have a SCHEMA.OBJECT format of your SERVERNAME\INSTANCE values. Then, PARSENAME behave like having a simple object name in the string.
How about the following (SQL Fiddle):
SELECT m.name,
LEFT(m.name, CHARINDEX('\', m.name) - 1) AS column1,
RIGHT(m.name, LEN(m.name) - CHARINDEX('\', m.name)) AS column2
FROM MyTable m
How to handle strings with no \ in them (SQL Fiddle):
SELECT m.name,
CASE WHEN CHARINDEX('\', m.name) = 0 THEN ''
ELSE LEFT(m.name, CHARINDEX('\', m.name) - 1) END AS column1,
CASE WHEN CHARINDEX('\', m.name) = 0 THEN ''
ELSE RIGHT(m.name, LEN(m.name) - CHARINDEX('\', m.name)) END AS column2
FROM MyTable m;
You can use CHARINDEX to check for the character position of the splitter ('/') and use SUBSTRING to split the string.
However care has to be taken to ensure you handle records without splitters else you would invoke an error.
Also in the case where splitter is unavailable, decision has to be made as to which column the data should be mapped to. Here I am mapping data to FirstName and assigning NULL to LastName
DECLARE #TableBuyer TABLE (ID INT, FullName VARCHAR(100))
INSERT INTO #TableBuyer
SELECT '1','Bryan/Greenberg' UNION ALL
SELECT '2','Channing/Tatum' UNION ALL
SELECT '3','Paul/William' UNION ALL
SELECT '4','EricBana' UNION ALL
SELECT '5','James/Lafferty' UNION ALL
SELECT '6','Wentworth/Miller'
SELECT
CASE
WHEN CHARINDEX('/', FullName) > 0 THEN SUBSTRING(FullName, 1, CHARINDEX('/', FullName) - 1)
ELSE FullName
END AS FirstName
,
CASE
WHEN CHARINDEX('/', FullName) > 0 THEN SUBSTRING(FullName, CHARINDEX('/', FullName) + 1, LEN(FullName))
ELSE NULL
END AS LastName
FROM #TableBuyer;
DECLARE #TableBuyer TABLE (ID INT, FullName VARCHAR(100))
INSERT INTO #TableBuyer
SELECT '1','Bryan/Greenberg' UNION ALL
SELECT '2','Channing/Tatum' UNION ALL
SELECT '3','Paul/William' UNION ALL
SELECT '4','EricBana' UNION ALL
SELECT '5','James/Lafferty' UNION ALL
SELECT '6','Wentworth/Miller'
select left(FullName, len(FullName)-CHARINDEX('/', REVERSE(FullName))) as firstname,
substring(FullName, len(FullName)-CHARINDEX('/', REVERSE(FullName))+ 2, len(FullName)) as lastname
from #TableBuyer
OR
select left(FullName, len(FullName)-CHARINDEX('/', REVERSE(FullName))) as firstname,
RIGHT(FullName, len(FullName)-CHARINDEX('/', FullName)) as lastname
from #TableBuyer
There is no "simple" method. Something like this should work:
select left(col, charindex('\', col) - 1) as column1,
right(col, charindex('\', reverse(col)) - 1) as column2
You might need to double up on the backslash ('\\') to get it to work properly.

Remove part of a text string

SELECT
right(name,7),
substring(params, charindex('|-|', params)+3,LEN(params)) as 'List Name',
convert(varchar,dateadd(hh,-8,created_date), 101) as Date,
convert(char, dateadd(hh,-8,created_date), 108) as Time
FROM
[meldb].[dbo].[mr_message]
WHERE
name in ('CL_LIST_STARTED', 'CL_LIST_STOPPED')
AND dateadd(hh,-8,created_date) > '7/1/2014'
ORDER BY
created_date ASC
List name will return something like:
firstname.lastname-|LISTNAME|-|PARENTLISTNAME
I'm trying to isolate LISTNAME and PARENTLISTNAME into separate columns, but since they can vary in char size I can't just specify right or left
Btw I didn't create this table I'm just stuck using it
Any ideas?
Did you try it yet?
Ok... happy friday :)
declare #str varchar(100);
set #str = 'jim.smith|-|firstItem|-|secondItem';
--- for your query, change #str to the column name, obviously ---
select
substring(
#str
, charindex('|-|', #str) + 3
, ( ( charindex('|-|', #str, charindex('|-|', #str) + 3) ) - ( charindex('|-|', #str) + 3) )
)
,substring(
#str
, charindex('|-|', #str, charindex('|-|', #str) + 3) + 3
, len(#str) -- guaranteed to be past the end, to catch all
)
Do you want to split params into three columns? Please check below query.
SELECT
SUBSTRING(params, 1, CHARINDEX('-', params)-1) AS FullName,
SUBSTRING(STUFF(params, CHARINDEX('|-|', params), LEN(params), ''), CHARINDEX('-', params) + 2, LEN(params)) AS 'List Name',
SUBSTRING(params, CHARINDEX('|-|', params) + 3, LEN(params)) AS 'Parent List Name',
CONVERT(VARCHAR,DATEADD(hh,-8,created_date), 101) AS DATE,
CONVERT(CHAR, DATEADD(hh,-8,created_date), 108) AS TIME
FROM
[meldb].[dbo].[mr_message]
WHERE
name IN ('CL_LIST_STARTED', 'CL_LIST_STOPPED')
AND DATEADD(hh,-8,created_date) > '7/1/2014'
ORDER BY
created_date ASC
Here is the format I came up with using PAT index and the separators you mentioned:
SELECT name,
substring(name, 0, charindex('.', name)) as 'FirstName',
substring(name, charindex('.', name) + 1, patindex('%|-|%', name) - patindex('%-|%', name) -2) as 'LastName',
substring(name,patindex('%-|%', name)+2, patindex('%|-|%', name) - patindex('%-|%', name)-2) as 'ListName',
substring(name, patindex('%|-|%', name)+3, len(name) - patindex('%|-|%', name)) as 'ParentListName'
from FancyNames
Link to SQL Fiddle: http://sqlfiddle.com/#!6/03c2c/38