sql parse full name field into first, middle, last, and suffix - sql-server-2008

I'm trying to split full names into last, first, middle, and suffix. I searched but couldn't find the exact the same format as mine. I have the following code, but I'm getting this error when running the full select.
Msg 537, Level 16, State 3, Line 1
Invalid length parameter passed to the LEFT or SUBSTRING function.
SpaceComma table gets the correct indexes.
This is the format of the names I have:
CREATE TABLE #myfullnames (fullName VARCHAR(50))
GO
INSERT #myfullnames VALUES ('BROOK SR, JAMES P.')
INSERT #myfullnames VALUES ('BLOCK JR., BILL V.')
INSERT #myfullnames VALUES ('MOOR, CLODE M.')
INSERT #myfullnames VALUES ('SOUDER III, Laurence R.')
INSERT #myfullnames VALUES ('SOUDER, WILL' )
INSERT #myfullnames VALUES ('KOLIV, Kevin E.')
INSERT #myfullnames VALUES ('Simk, JR. Thomas Todd')
INSERT #myfullnames VALUES ('Polio, Gary R.')
I would appreciate your help. Thanks.
select SplitNames.LastName, SplitNames.FirstName,
SplitNames.MiddleName, SplitNames.Title
from (
select [fullName]
, substring([fullName], 1, SpceTitle-1) as LastName
, substring([fullName], SpceMid,(SpceMid - SpceFirstName - 1)) as FirstName
, substring([fullName], SpaceComma.SpceTitle, (SpaceComma.SpceFirstName -
SpaceComma.SpceTitle)) as Title
, nullif(substring([fullName],SpaceComma.SpceMid+1,100),'') as
MiddleName
from (
select [fullName],
charindex(',',[fullName]) as Comma,
charindex(' ',[fullName]+space(1),charindex(',',[fullName])) as
SpceFirstName,
(len([fullName]) + 1 - charindex(' ',reverse([fullName]), 0)) as
SpceMid,
charindex(' ',[fullName], charindex (' ',reverse([fullName]))) as SpceTitle
from #myfullnames
) SpaceComma
) SplitNames
DROP TABLE #myfullnames

The data in your example does not follow any fixed set of rules so there will not be a perfect solution for parsing the names. An example of the rule violation is between "Simk" and "BLOCK" in that the "JR" is inside the comma on one and not the other. The only solution to the rule violation is to manually correct the violators.
We can parse the name using the "PARSENAME" function in SQL Server. SQL Server uses PARSENAME to seperate the SERVERNAME.DATABASE.SCHEMA.TABLE and is limited to four parts.
Here is a query which parses the names
select fullname
, REPLACE(fullname,'.','') AS [1]
, REPLACE(REPLACE(fullname,'.',''),', ','.') AS [2]
, ParseName(REPLACE(REPLACE(fullname,'.',''),', ','.'),2) AS [3]
, REPLACE(ParseName(REPLACE(REPLACE(fullname,'.',''),', ','.'),1),' ','.') AS [4]
, PARSENAME(REPLACE(ParseName(REPLACE(REPLACE(fullname,'.',''),', ','.'),1),' ','.'),1) AS [5]
, PARSENAME(REPLACE(ParseName(REPLACE(REPLACE(fullname,'.',''),', ','.'),1),' ','.'),2) AS [6]
from #myfullnames
The six output columns demonstrate the use of replacing characters with the "." then using PARSENAME to extract a portion of the string.

Related

Split column value and return split values appropriately

I have below table (MYSQL),
CREATE TABLE x_table (name VARCHAR(100), currencyType VARCHAR(100));
INSERT INTO x_table VALUES ('Rupee', '5X34'), ('Dollar', '3X34$'), ('Yen', '7X57');
I want to split currencyType column into two.
split currentyType column by X
return count (count must be an int value - not string)
for Rupee - count is 5,
for Dollar - count is 3
return type
for Rupee - 34 doesn't contain $, so type will be 'Non-dollar'
for dollar - 34$ contains $, type would be "dollar'
for yen - 57 doesn't contain $, type would be "Non-dollar'
Tried
select name,
SUBSTRING_INDEX(currencyType, 'X', 1) as count,
SUBSTRING_INDEX(currencyType, 'X', 2) as type
from x_table
but not sure how to implement it correctly.
DEMO
Modify your query as the following:
SELECT
name,
CAST(SUBSTRING_INDEX(currencyType, 'X', 1) AS UNSIGNED) AS count,
CASE
WHEN INSTR(SUBSTRING_INDEX(currencyType, 'X', -1), '$')
THEN 'dollar' ELSE 'Non-dollar'
END AS type
FROM x_table
See demo
CAST(SUBSTRING_INDEX(currencyType, 'X', 1) AS UNSIGNED): this will cast the left part of the string as positive number.
To start searching the string from right (get the right part of the string), use -1 instead of 1 for the number parameter in the substring_index function
The INSTR function check if the string contains '$' or not.

How Split Json with oracle 19

Is there a way to take out part of a json?
I just want the common object without zona and central.
I have the following table
CREATE TABLE FB_TAB
( COL CLOB COLLATE USING_NLS_COMP,
ID NUMBER,
TYPE VARCHAR2(20 BYTE) COLLATE USING_NLS_COMP,
COLOR VARCHAR2(20 BYTE) COLLATE USING_NLS_COMP,
AMOUNT NUMBER,
APP VARCHAR2(20 BYTE) COLLATE USING_NLS_COMP,
CONSTRAINT JSON_CON_1 CHECK (col IS JSON) ENABLE
)
and its insert
insert into fb_tab
values('
{"common":{"contrato":{"id":"1","codigo":"054AKSDJ","nombre":"BUCLE"},"servicio":"","actividad":"Apertura","tipo_actividad":"BAJA","numero_administrativo":"","estado_origen":"Pendiente","provincia":{"id":"24","nombre":"León"},"aplicacion_origen":{"id":"1","nombre":"VISORD"},"zona":{"pais":"ES","cliente":"TL","div_geo":"2410002"},"central":{"codigo":"2410002","nombre":"Leon-Torre"},"clave":{"act_domiciliaria":"","prioridad":""}},"app_log":{"app_name":"client_mobile"}}
', 23, 'Ball', 'Red', 15, 'Mobile');
commit;
I want to get the next JSON as a result
{"Type":"Ball","Color":"Red","App":"Mobile","Amount":"15","my_json":{"contrato":{"id":"1","codigo":"054AKSDJ","nombre":"BUCLE"},"servicio":"","actividad":"Apertura","tipo_actividad":"BAJA","numero_administrativo":"","estado_origen":"Pendiente","provincia":{"id":"24","nombre":"León"},"aplicacion_origen":{"id":"1","nombre":"VISORD"},"clave":{"act_domiciliaria":"","prioridad":""}}}
I'm trying with this query
SELECT JSON_OBJECT (
'Type' value to_char(a.Type),
'Color' value to_char(a.Color),
'App' value to_char(a.App),
'Amount' value to_char(a.Amount),
'my_json' VALUE treat ( JSON_QUERY(a.col, '$.common' WITHOUT WRAPPER) as json )
)
--into json_output
FROM FB_TAB a
where a.id = :id;
but my actual result is this
{"Type":"Ball","Color":"Red","App":"Mobile","Amount":"15","my_json":{"contrato":{"id":"1","codigo":"054AKSDJ","nombre":"BUCLE"},"servicio":"","actividad":"Apertura","tipo_actividad":"BAJA","numero_administrativo":"","estado_origen":"Pendiente","provincia":{"id":"24","nombre":"León"},"aplicacion_origen":{"id":"1","nombre":"VISORD"},"zona":{"pais":"ES","cliente":"TL","div_geo":"2410002"},"central":{"codigo":"2410002","nombre":"Leon-Torre"},"clave":{"act_domiciliaria":"","prioridad":""}}}
I don't want to see zona and central
Is there a way to do this ?
Best regards
You have a mistake inside the JSON you're trying to insert into the table
Here's the revised insert statement
I've broke it down in pieces trying to fix it, feel free to "unwrap" it in a single line
insert into fb_tab
values('
{"common":
{"contrato":{"id":"1","codigo":"054AKSDJ","nombre":"BUCLE"},
"servicio":"",
"actividad":"Apertura",
"tipo_actividad":"BAJA",
"numero_administrativo":"",
"estado_origen":"Pendiente",
"provincia":{"id":"24","nombre":"León"},
"aplicacion_origen":{"id":"1","nombre":"VISORD"},
"clave":{"act_domiciliaria":"","prioridad":""}
},
"zona":{"pais":"ES","cliente":"TL","div_geo":"2410002"},
"central":{"codigo":"2410002","nombre":"Leon-Torre"},
"app_log":{"app_name":"client_mobile"}
}',
23, 'Ball', 'Red', 15, 'Mobile');
Basically you were placing clave after central and closing it with two curly brackets (}) making the common to include zona and central, that you were trying to exclude from the result of the query.
Now when you query the table
SELECT JSON_OBJECT (
'Type' value to_char(a.Type),
'Color' value to_char(a.Color),
'App' value to_char(a.App),
'Amount' value to_char(a.Amount)
,'my_json' VALUE treat ( JSON_QUERY(a.col, '$.common' WITHOUT WRAPPER) as json )
)
FROM FB_TAB a
where a.id = 23;
Removed the :id bind to ease the debugging process
You get the desired result
{"Type":"Ball","Color":"Red","App":"Mobile","Amount":"15","my_json":{"contrato":{"id":"1","codigo":"054AKSDJ","nombre":"BUCLE"},"servicio":"","actividad":"Apertura","tipo_actividad":"BAJA","numero_administrativo":"","estado_origen":"Pendiente","provincia":{"id":"24","nombre":"León"},"aplicacion_origen":{"id":"1","nombre":"VISORD"},"clave":{"act_domiciliaria":"","prioridad":""}}}

How do I remove unknown characters in a string?

I would like to delete parts of an string.
We have a Table: Locations
mk-MK=New York; sq-AL=Nej York; en-US=New York
mk-MK=London; sq-AL=London; en-US=London
mk-MK=Paris; sq-AL=Paris; en-US=Paris
I Want to remove everything and keep only sq-AL=LocationName.
I want the result to be:
sq-AL=Nej York;
sq-AL=London;
This is yet another example of the importance of normalized databases.
In a normalized database you would have a table with 2 columns, one for the culture (sq-Al, en-US etc`) and one for the value. I would go a step further and have the cultures in a lookup table.
However, since this is not the case you have to use string manipulations to get the value of a specific culture. you can use SUBSTRING and CHARINDEX to find the specific pattern you want.
This will work in any of the cases represented by the sample data I've listed.
-- Create the table and insert sample data
CREATE TABLE Location ([Name] varchar(100))
INSERT INTO Location ([Name]) VALUES
('en-US=Huston; mk-MK=Huston; sq-AL=Huston;'), -- end of the row, with the ending ';'.
('en-US=New York; mk-MK=New York; sq-AL=Nej York'), -- end of the row, without the ending ';'.
('mk-MK=London; sq-AL=London; en-US=London'), -- middle of the row
('sq-AL=Paris; en-US=Paris; mk-MK=Paris') -- begining of the row
SELECT SUBSTRING(Name,
CHARINDEX('sq-AL=', Name), -- index of 'sq-AL='
CASE WHEN CHARINDEX(';', Name, CHARINDEX('sq-AL=', Name)) > 0 THEN -- If there is a ';' after 'sq-AL='.
CHARINDEX(';', Name, CHARINDEX('sq-AL=', Name)) -- index of the first ';' after 'sq-AL='
- CHARINDEX('sq-AL=', Name) -- index of the first ';' - the index of 'sq-AL=' will give you the length for `Nej York`
ELSE
LEN(Name)
END
) + ';'
FROM Location
-- Cleanup
DROP Table Location
You can use CHARINDEX function. I've tried same with a variable as,
declare #locations varchar(100) = 'mk-MK=New York; sq-AL=Nej York; en-US=New York'
select LEFT(
RIGHT(
#locations, LEN(#locations)-CHARINDEX(';',#locations)
--output here : sq-AL=Nej York; en-US=New York
)
,CHARINDEX(';',#locations)
) + ';'
--Final Output : sq-AL=Nej York;
In your case: Query will be as,
select LEFT(
RIGHT(
Name, LEN(Name)-CHARINDEX(';',Name)
--output here : sq-AL=Nej York; en-US=New York
)
,CHARINDEX(';',Name)
) + ';'
FROM Locations

Get a value in a single cell into multiple rows using SSRS

One particular field in the SQL Table has a value in the below format.
Value11,value12,Value13
Value21,value22,value23
...
...
I need to get each of the above lines in the text into individual lines using SSRS.
for example I will get 2 rows in the report for above data.
Is there a way to do this using a reporting project in VS or Report builder?
Thanks in advance.
Update
Hi,Below is the DDL for the table
tblTest
[id] int
[Description] VARCHAR(MAX)
Lets assume there is only one record with Below
Insert Into tblTest
([id],[Description])
VALUES
(1, 'Value11,value12,Value13
Value21,value22,value23')
So there is a carriage return Caharacter in above Insert for the Description column. This will have 2 lines in the description row.
So my requirement is that when i retrieve the data, I should get into below format.
ID, Description
1, Value11,value12,Value13
1, Value21,value22,value23
You can use this SELECT for passing data to Reporting Services.
SELECT t1.id, t2.splittedDescriptions
FROM
(
SELECT tblTest.id,
CAST('<row>' + REPLACE(tblTest.[Description], CHAR(13) + CHAR(10), '</row><row>') + '</row>' AS XML) as xmlRow
FROM tblTest
) t1
CROSS APPLY
(
SELECT xmlTable.splittedRow.value('.', 'VARCHAR(MAX)') as splittedDescriptions
FROM t1.xmlRow.nodes('/row') AS xmlTable(splittedRow)
) t2
It uses XML and nodes() method to split your description when it finds a CRLF.
It work with a single CRLF, if you need to work with double CRLF you can simply modify the SELECT.
Example - input data:
INSERT INTO tblTest ([id],[Description]) VALUES
(1, 'val11, val12, val13' + CHAR(13) + CHAR(10) + 'val21, val22, val23')
INSERT INTO tblTest ([id],[Description]) VALUES
(2, 'val31, val32, val33')
INSERT INTO tblTest ([id],[Description]) VALUES
(3, 'val41, val42, val43' + CHAR(13) + CHAR(10) + 'val51, val52, val53' + CHAR(13) + CHAR(10) + 'val61, val62, val63')
Example - output:
id splittedDescriptions
----------- --------------------
1 val11, val12, val13
1 val21, val22, val23
2 val31, val32, val33
3 val41, val42, val43
3 val51, val52, val53
3 val61, val62, val63
use this,
select '1' as Id, Value11+','+value12+','+Value13 as Description into tblTest from XYZ;
Value11,value12,Value13 all should be in String

What am I doing wrong with my query syntax?

I am trying to insert a row into my table with the following query in ssms:
INSERT INTO [Reservation].[dbo].[Contacts]
([ContactID]
,[Name]
,[Phone]
,[Email]
,[QoowayUserName])
VALUES
(<"100", nvarchar(50),>
,<"Vincent Chase", nvarchar(50),>
,<"3103331234", nvarchar(50),>
,<"vincent_chase#hollywood.com", nvarchar(50),>
,<"Username", nvarchar(50),>)
GO
I get the error:
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near '<'.
I've also tried using single quotes. What am I doing wrong?
INSERT INTO Reservation.dbo.Contacts
(ContactID
,Name
,Phone
,Email
,QoowayUserName)
VALUES
('100'
,'Vincent Chase'
,'3103331234'
,'vincent_chase#hollywood.com'
,'Username')
You might need to remove the "dbo", like this:
INSERT INTO Reservation.Contacts
(ContactID
,Name
,Phone
,Email
,QoowayUserName)
VALUES
('100'
,'Vincent Chase'
,'3103331234'
,'vincent_chase#hollywood.com'
,'Username')