Can someone give me tips on how to use the substring function - sql

I have a query where the first column display name length the second is title or courtesy I have done those but I'm having trouble with my third column. It is supposed to use substring and display first name initial and last name initial can anyone tell me how to add this function to what I already have?
Here is the query
SELECT 'Your full name is ' + CAST(LEN(FirstName) + LEN(LastName) AS VARCHAR(12)) + ' character(s).' AS [Length of Employee Name],
CASE TitleOfCourtesy WHEN 'Mr.' THEN 'Mister '
WHEN 'mrs. ' THEN 'Miss'
WHEN 'Ms.' THEN 'Miss '
WHEN 'Dr.' THEN 'Doctor '
ELSE '' END + TitleOfCourtesy + LastName AS title
FROM dbo.Employees

(since you used LEN I assume you are using SQL Server)
You mean something like this?
substring(FirstName,1,1) + substring(LastName,1,1)
In general it is like this :
substring(expression, startPosition, lenght)

I would use LEFT() instead of substring.
DECLARE #Employees TABLE (FirstName VARCHAR(25),LastName VARCHAR(25), TitleOfCourtesy VARCHAR(5))
INSERT INTO #Employees
VALUES ('Bob','Brown','Mr.'),
('Olivia','Taylor','M rs.'),
('Grace','Stevens','Ms.'),
('Theodor','Seuss','Dr.');
SELECT 'Your full name is ' + CAST(LEN(FirstName) + LEN(LastName) AS VARCHAR(12)) + ' character(s).' AS [Length of Employee Name],
CASE Replace(TitleOfCourtesy, ' ','') --Gets rid of any white space
WHEN 'Mr.' THEN 'Mister'
WHEN 'mrs.' THEN 'Miss'
WHEN 'Ms.' THEN 'Miss'
WHEN 'Dr.' THEN 'Doctor'
ELSE ''
END + ' ' + LastName AS title,
CONCAT(LEFT(FirstName,1),'.',LEFT(LastName,1),'.') AS Initials
FROM #Employees
Results:
Length of Employee Name title Initials
-------------------------------------------- -------------------------------- --------
Your full name is 8 character(s). Mister Brown B.B.
Your full name is 12 character(s). Miss Taylor O.T.
Your full name is 12 character(s). Miss Stevens G.S.
Your full name is 12 character(s). Doctor Seuss T.S.

Related

Split name into multiple parts in SELECT statement

I cannot seem to find an existing post on splitting a string into the parts I require. I have a database field in SQL Server that contains the "LastName FirstName MI" (no commas just spaces delimiting each part of a person's name). I have the following SQL to get the FirstName and Last, but cannot figure out how to get the Middle Initial or Middle Name.
Ex. Doe John B
SELECT
RTRIM(LEFT([PATIENT_NAME], CHARINDEX(' ', [PATIENT_NAME]))) AS LastName,
SUBSTRING([PATIENT_NAME], CHARINDEX(' ', [PATIENT_NAME]) + 1, LEN([PATIENT_NAME])) AS FirstName
FROM
Clients
Results in:
FirstName = John B
LastName = Doe
How to just return the first name without the middle initial and get the 'B' as middle name from this string in this SELECT statement?
You can either take the right 1 character, or reverse the string the take the first char.
SELECT RIGHT(LTRIM(RTRIM([Patient_Name])), 1) AS Middle_Initial
SELECT LEFT(REVERSE(LTRIM(RTRIM([Patient_Name]))), 1) AS Middle_Initial
As for removing MI from your firstname string, I would either find the length of the string and take the left N-2 chars or I would charindex the space and then take that many chars. To put it all together:
DECLARE #name VARCHAR(100) = 'Smith David M '
--Clean the string of leading/trailing whitespace
SELECT LTRIM(RTRIM(#name)) AS name_cleaned
--Find the first space to parse out the last name
SELECT CHARINDEX(' ', #name) AS first_space
--Select all chars before the first space
SELECT LEFT(LTRIM(RTRIM(#name)), CHARINDEX(' ', #name)-1) AS last_name
--Find the next space, use the starting location as the previous space and add 1
SELECT CHARINDEX(' ', #name, 7) AS second_space
--Select all chars between the spaces
SELECT SUBSTRING(#name, CHARINDEX(' ', #name)+1, CHARINDEX(' ', #name, 7) - CHARINDEX(' ', #name)) AS first_name
--Select the right most char for middle initial
SELECT RIGHT(LTRIM(RTRIM(#name)), 1) AS middle
You can REPLACE the space characters with period characters (.) and use PARSENAME().
Note that this would work for all 3 parts of the name, not just the middle initial.
When using the CHARINDEX on the last name, you'll use it as the length of the substring. Then, on the FirstName, use it again as start position on the substring. Now, the trick on the Middle, on the CHARINDEX, you have to include the start position which will be the LEN minus the LastName CHARINDEX. this would gives you the second space which is the position you want to start with for taking the Middle Name.
See the example below :
DECLARE #tb TABLE (PATIENT_NAME varchar(250));
INSERT INTO #tb VALUES
('Doe John B')
DECLARE
#LastName INT
, #Middle INT
SELECT
#LastName = CHARINDEX(' ', PATIENT_NAME)
, #Middle = CHARINDEX(' ', PATIENT_NAME, LEN(PATIENT_NAME) - CHARINDEX(' ', PATIENT_NAME))
FROM #tb
SELECT
SUBSTRING(PATIENT_NAME, 1, #LastName) LastName
, SUBSTRING(PATIENT_NAME, #LastName, LEN(PATIENT_NAME) - #LastName) FirstName
, SUBSTRING(PATIENT_NAME, #Middle, LEN(PATIENT_NAME) - #Middle + 1 ) Middle
FROM #tb
I have declared some variables to make things much readable, but you can do it without them.
Surely, LEFT and RIGHT are the easier approaches on taking the lastname and Middle Name. Along with using some helper functions such as REVERSE and TRIM, but I would prefer PARSENAME as a simpler and cleaner approach.
Here is an example :
SELECT
PARSENAME(REPLACE(PATIENT_NAME,' ','.'),3) LastName
, PARSENAME(REPLACE(PATIENT_NAME,' ','.'),2) FirstName
, PARSENAME(REPLACE(PATIENT_NAME,' ','.'),1) Middle
Since the number of elements you must extract from your string is fixed(3) you can use XML based split:
DECLARE #clients TABLE (PATIENT_NAME nvarchar(max));
INSERT INTO #clients VALUES
(' Doe John B ')
,(' Doe Jane C ')
,(' Doe Jill ')
;WITH Splitted
AS (
SELECT PATIENT_NAME as ORIGINAL_PATIENT_NAME
,REPLACE(REPLACE(REPLACE(ltrim(rtrim(PATIENT_NAME)),' ','<>'),'><',''),'<>',' ') as PATIENT_NAME
,CAST('<x>' + REPLACE(REPLACE(REPLACE(REPLACE(ltrim(rtrim(PATIENT_NAME)),' ','<>'),'><',''),'<>',' '), ' ', '</x><x>') + '</x>' AS XML) AS Parts
FROM #clients
)
SELECT
ORIGINAL_PATIENT_NAME
,PATIENT_NAME
,Parts.value(N'/x[1]', 'nvarchar(max)') AS LAST_NAME
,Parts.value(N'/x[2]', 'nvarchar(max)') AS FIRST_NAME
,Parts.value(N'/x[3]', 'nvarchar(max)') AS MIDDLE_NAME
FROM Splitted
Results:
As you can see it works even with random-spaced names.

SQL Server Computed Column Trim

I am trying to add a computed column to an SQL database. The Computed Column Specification looks like this
BusinessName + ' ' + Surname + ' ' + FirstName
which works fine.
Often the BusinessName is blank so I want to Trim it
Trim(BusinessName + ' ' + Surname + ' ' + FirstName)
But when I do I get an error
You can use below logic,
First option: check if value is null, replace it by empty string, you will have leading empty space if BusinessName is null
isnull(BusinessName, '') + ' ' + Surname + ' ' + FirstName
or
Second option: check if BusinessName is empty or null, do not take into account if so. You won't have leading empty space if BusinessName is null or empty
case when isnull(BusinessName, ' ') <> ' '
then BusinessName + ' ' + Surname + ' ' + FirstName
else Surname + ' ' + FirstName
end as FullName
I think it depends by column datatypes and constraints. A more general approach could be the following. Starting from this if as a rule SURNAME and NAME (for instance) are not NULLABLE and cannot be blank, you can omit some of the functions:
DECLARE #T AS TABLE (BUSIN_NAME VARCHAR(20), SURNAME VARCHAR(20), NAME VARCHAR(20))
INSERT INTO #T VALUES(NULL, NULL, NULL);
INSERT INTO #T VALUES(NULL, 'A', NULL);
INSERT INTO #T VALUES(NULL, 'B ', NULL);
INSERT INTO #T VALUES('', 'Karl ', ' Smith');
INSERT INTO #T VALUES('Dr.', 'Karl ', ' Smith');
INSERT INTO #T VALUES('Dr. ', 'Joe ', ' Martin ');
SELECT BUSIN_NAME, SURNAME, NAME
, LTRIM(RTRIM( LTRIM(RTRIM(ISNULL(BUSIN_NAME,'')))+ ' ' + LTRIM(RTRIM(ISNULL(SURNAME,'')))+' ' +LTRIM(RTRIM(ISNULL(NAME,''))))) DESCR
, DATALENGTH ( LTRIM(RTRIM( LTRIM(RTRIM(ISNULL(BUSIN_NAME,'')))+ ' ' + LTRIM(RTRIM(ISNULL(SURNAME,'')))+' ' +LTRIM(RTRIM(ISNULL(NAME,''))))) ) AS LENGTH
FROM #T
OUtput:
BUSIN_NAME SURNAME NAME DESCR LENGTH
NULL NULL NULL 0
NULL A NULL A 1
NULL B NULL B 1
Karl Smith Karl Smith 10
Dr. Karl Smith Dr. Karl Smith 14
Dr. Joe Martin Dr. Joe Martin 14
I would suggest doing the following:
select stuff( (coalesce(' ' + BusinessName, '') +
coalesce(' ' + Surname, '') +
coalesce(' ' + Firstname, '')
), 1, 1, '')
These easily generalizes to more fields. You can use ltrim() rather than stuff(), because you are using spaces as a separator. stuff() is more general, because it handles other separators (notably commas).
As a computed column:
alter table t add newcol as
(stuff( (coalesce(' ' + BusinessName, '') +
coalesce(' ' + Surname, '') +
coalesce(' ' + Firstname, '')
), 1, 1, ''
)
)

Creating a view. Replacing a NULL value with an empty string. SQL

I want to create a view from a table where we have a FirstName, LastName and MiddleName column and where the MiddleName might be NULL, plus a salary. I need to replace the MiddleName with and empty string where there's not MiddleName. I'm using SQL Management Studio.
I came up with this code:
CREATE VIEW V_EmployeeNameJobTitle AS
SELECT FirstName + ' ' + MiddleName + ' ' + LastName AS [Fullname], Salary FROM Employees WHERE MiddleName IS NOT NULL
UNION SELECT FirstName + ' ' + LastName AS [Fullname], Salary FROM Employees WHERE MiddleName IS NULL
But this doesn't seem to work as I wanted to, and it's not very pretty. Any other suggestions how I might shorten this. Thanks in advance.
Use the ISNULL() function, where it replaces the NULL value int the value you choose. for ex:
CREATE VIEW V_EmployeeNameJobTitle AS
SELECT FirstName + ' ' + ISNULL(MiddleName, '') + ' ' + LastName AS [Fullname], Salary
FROM Employees
or if you don't want to get 2 spaces when the middle name is null, you can undergo the following:
CREATE VIEW V_EmployeeNameJobTitle AS
SELECT (CASE WHEN MiddleName IS NULL THEN FirstName + ' ' + LastName
ELSE FirstName + ' ' + MiddleName + ' ' + LastName END) AS [Fullname],
Salary
FROM Employees
SELECT FirstName + ' ' +
(case when MiddleName is null then '' else MiddleName + ' ' end) +
LastName AS [Fullname]
use IsNull function
CREATE VIEW V_EmployeeNameJobTitle AS
SELECT FirstName + ' '
+ MiddleName + ' '
+ IsNull(LastName, '') AS [Fullname]
, Salary
FROM Employees

SQL-Server CONCAT case

I have the following exercise:
concatenate first, middle, last name and name suffix to form the
customer’s name in the following format: FirstName [MiddleName.]
LastName[, Suffix]. Note that NULL values should be omitted.
I interpret this as the following scenario (created the table from the image and inserted some values):
Please find my sample data below, name is #TB_Customer
The column CustomerName is the expected result and should be of form
FirstName MiddleName.LastName, Suffix if i have enteries for all
the fields.
MiddleName and Suffix can be optional, so the cases are:
If there is a suffix but not a MiddleName then CustomerName
should be of form Firstname LastName,Suffix
If there is a MiddleName but not a suffix then CustomerName
should be of form FirstName MiddleName.LastName
If both MiddleName and Suffix are null then CustomerName should
be of form FirstName LastName)
This is what i'm getting:
But as you can see the CustomerName case query I wrote doesn't work as expected (please see the cases above with bullets)
The query I wrote to get the CustomerName column is:
SELECT
(case
when (MiddleName is not null and Suffix is not null) then
CONCAT(c.FIRSTNAME,' ', c.MiddleName,'.', c.LASTNAME, ', ',Suffix)
when (MiddleName is null and suffix is null) then
CONCAT(c.FIRSTNAME,' ' ,c.LASTNAME)
when (MiddleName is null and Suffix is not null )then
concat (c.FirstName, ' ', c.LastName, ', ',Suffix )
when (Suffix is null and MiddleName is not null) then
concat (c.FirstName, ' ',MiddleName,'.',LastName)
end
)AS CustomerName
,c.*
FROM #TB_Customer c;
I have 2 questions:
Did I understand the exercise and do i have a good logic?
Where have I made a mistake and what's the correct query?
Using SQL-Server 2012
edit
to recreate my scenario please see the code below (sorry for not linking a fiddle but the website is not responding at my current location)
CREATE TABLE #TB_Customer
(
CustomerID int , --PK
Title varchar(50),
FirstName varchar(50),
MiddleName varchar(50),
LastName varchar(50),
Suffix varchar(50),
EmailAddress varchar(50),
Phone varchar(50),
Gender varchar(50),
Birthdate varchar(50),
--no fk
PRIMARY KEY (CustomerID)
)
insert into #TB_Customer values
('1','Sir','John','Jacob','Adams','St','johnJacobAdams#gmail.com','0677731235','M','1989-04-06'),
('2','Mr.','Russel','Thyrone','Peterson','pr','thyronePeterson#yahoo.com','555-010405','M','1963-02-01'),
('3','Ms.','Anne','Candice','Acola','aca','CandiceA#gmail.com','07408989989','F','1988-05-19'),
('4','Mrs.','Sophia','Veronika','Turner','tvs','SophiaVT#facebook.de','0423423887','F','1983-06-20'),
('5','Ms','Margaret','','Delafleur','','delaMarg#yahoo.co','233223355','Female','1982-02-25'),
('6','Mrs','Jessica','Luana','Cruz','','Jess#yahoo.com','787876631','Female','1922-05-05'),
('7','Mr','Dyrius','','Cruz','dc','dyr33#yahoo.com','0673332211','Male','1987-03-01')
update #TB_Customer
set Gender = 'Male' where Gender = 'M'
update #TB_Customer
set Gender = 'Female' where Gender = 'F'
Something like this should work as well...
SELECT concat(firstname
,CASE WHEN ISNULL(middlename,'') <> '' THEN ' '+middlename+'.'
WHEN ISNULL(middlename,'') <> '' AND ISNULL(suffix,'') = '' THEN '.'
ELSE ' ' END
,lastname
,CASE WHEN ISNULL(suffix,'') <> '' THEN ', '+suffix END)
FROM #TB_Customer
OUTPUT:
John Jacob.Adams, St
Russel Thyrone.Peterson, pr
Anne Candice.Acola, aca
Sophia Veronika.Turner, tvs
Margaret Delafleur
Jessica Luana.Cruz
Dyrius Cruz, dc
John Adams, St
I cant see the error in you query, i know if one of the columns is null, all the others will be, but try this way:
SELECT COALESCE(c.FIRSTNAME,'') + ' ' +
CASE WHEN COALESCE(c.MiddleName,'') = ''
THEN ''
ELSE c.MiddleName + '.'
END
+ COALESCE(c.LASTNAME,'') +
CASE WHEN COALESCE(Suffix,'') = ''
THEN ''
ELSE ', ' + Suffix
END AS CustomerName, c.*
FROM #TB_Customer c;
#Henrik is right, '' and NULL are diferent things
Now that you've given the code, I can see what the error is: The empty string is different from NULL.
So your tests for the presence of a middle name/suffix will always be true.
Either set those fields to NULL, or augment the test to check for NULL or empty strings.
SELECT
STUFF(RTRIM(
CONCAT(' ',
COALESCE(NULLIF(FirstName,'') + ' ', ''),
COALESCE(NULLIF(MiddleName,'') + '.', ''),
COALESCE(NULLIF(LastName,''), ''),
COALESCE(', ' + NULLIF(Suffix,'') , '')
)
), 2, 0,'')
FROM #TB_Customer tc
added the STUFF incase for some strange reason all you have is a Suffix

Combining two column's data into one column in SQL?

I am trying to combine Last name, first name and middle name into single sort name column in a SQL statement. Sometime middle name will be NULL, and if that's the case, the sort name is showing NULL.
How to handle this?
SELECT TOP 500
Last_Name, First_Name, Middle_Name,
[Last_Name] + ',' + [First_Name] + ' ' + [Middle_Name] AS SORT_NAME
FROM [dbo].[usr_CUSTOMER]
ORDER BY SORT_NAME
Results:
Last_Name First_Name MiddleName Sort_Name
Aa Robert NULL NULL
But I want to see sort_name to be 'Aa,Robert'.
COALESCE:
COALESCE([Last_Name], '') + ',' + COALESCE([First_Name], '') + ' ' +
COALESCE(
[Middle_Name], '') AS SORT_NAME
Of course, this will leave ugly commas when last name or both first and middle are empty, so your actual code will need to be a bit more clever.
Use the ISNULL() function - it replaces a NULL value with something you define:
SELECT TOP 500
Last_Name, First_Name, Middle_Name,
[Last_Name] + ',' + [First_Name] + ' ' + ISNULL([Middle_Name], '') as SORT_NAME
FROM [dbo].[usr_CUSTOMER]
ORDER BY SORT_NAME
You can use the ISNULL function
ISNULL ( check_expression , replacement_value )
Docs : http://msdn.microsoft.com/en-us/library/ms184325.aspx
Note that I moved the space separating First and Middle name inside the COALESCE so that you avoid having a trailing space when Middle name is NULL.
..., [Last_Name]+ ','+ [First_Name] + COALESCE(' '+ [Middle_Name],'') as SORT_NAME...
Try
CONCAT(firstname,' ', LastName,' ', MiddleName) AS Full_Name