SQL Server separate: FirstName, MiddleName and LastName - mysql

Good day!
I get a "Varchar" which is the full name of a client, and need to split this "varchar" as:
"FirstName MidleName MiddleNameTwo LastName "
Need to enter the "FirstName" on "Col1"
Need to enter the "MiddleName, MiddleNameTwo in" col2 "
Need to enter the "LastName" in "Col3"
Thanks for your help!

You Should use subqueries for this task
INSERT INTO names(firstname, middlename, lastname)
SELECT substringfunctionofyours(name), substringfunctionofyours(name),
substringfunctionofyours(name) FROM namefield
keep in mind this is just a dummy query it won't work if you use it like this

Can you change the input method to 4 separate fields ?
If you can't, then implement a specific delimeter between the different parts of the string ?
In cases where the last name is built with 2 words, there is no deterministic way of processing the string if the delimeter is [space] or any other character like '-' or ' which are common in names.
Using a delimeter like '|' :
Declare #FullName varchar(100) = 'FirstName|MidleName|MiddleNameTwo|LastName'
Print 'FirstName = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'MiddleName1 = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'MiddleName2 = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'LastName = ' + #FullName
This will also work if you don't have one of the parts, as long as you maintain the structure.
Declare #FullName varchar(100) = 'FirstName|MidleName||LastName'
Print 'FirstName = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'MiddleName1 = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'MiddleName2 = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'LastName = ' + #FullName

Let say you have a name like this "ABC DEF GHI"
now you want First Name, Middle Name and last Name From this string.
Here We Go
Select
Substring(Cast('ABC DEF GHI' as nvarchar),0,charindex(' ',Cast('ABC DEF GHI' as nvarchar))) as Col1,
Substring(Cast('ABC DEF GHI' as nvarchar),charindex(' ',Cast('ABC DEF GHI' as nvarchar)),4)as Col2,
Substring(Cast('ABC DEF GHI' as nvarchar),8,charindex(' ',Cast('ABC DEF GHI' as nvarchar)))as Col3
Note: This is MSSQL SERVER Query and Substring Function is Built in in MSSQL SERVER

Related

Convert result into doubly nested JSON format

I am trying to convert SQL Server results into a doubly nested JSON format.
Source SQL Server table:
ID
Name
Program
Type
Section
Director
Project
Sr Manager
PCM
Contractor
Cost Client
123
abc
qew
tyu
dd
ghghjg
hkhjk
fghfgf
gnhghj
gghgh
gghhg
456
yui
gdffgf
ghgf
jkjlkll
uiop
rtyuui
rfv
ujmk
rfvtg
efgg
Convert into doubly JSON as shown here:
[
[
{"key":"ID","value":"123"},
{"key":"Name","value":"abc"},
{"key":"Program","value":"qew"},
{"key":"Type","value":"tyu"},
{"key":"Section","value":"dd"},
{"key":"Director","value":"ghghjg"},
{"key":"Project","value":"hkhjk"},
{"key":"Sr Manager","value":"fghfgf"},
{"key":"PCM","value":"gnhghj"},
{"key":"Contractor","value":"gghgh"},
{"key":"Cost Client","value":"gghhg"}
],
[
{"key":"ID","value":"456"},
{"key":"Name","value":"yui"},
{"key":"Program","value":"gdffgf"},
{"key":"Type","value":"ghgfjhjhj"},
{"key":"Section","value":"jkjlkll"},
{"key":"Director","value":"uiop"},
{"key":"Project","value":"rtyuui"},
{"key":"Sr Manager","value":"rfv"},
{"key":"PCM","value":"ujmk"},
{"key":"Contractor","value":"rfvtg"},
{"key":"Cost Client","value":"efgg"}
]
]
Any help would be greatly appreciated.
Edit:
I started with this by rewriting the "FOR JSON AUTO" so that I can add "Key" "Value" text somehow.
But because my table has space in the column name, FOR XML PATH('') giving invalid XML identifier as required by FOR XML error.
that is when I thought of taking community help.
Create PROCEDURE [dbo].[GetSQLtoJSON] #TableName VARCHAR(255)
AS
BEGIN
IF OBJECT_ID(#TableName) IS NULL
BEGIN
SELECT Json = '';
RETURN
END;
DECLARE #SQL NVARCHAR(MAX) = N'SELECT * INTO ##T ' +
'FROM ' + #TableName;
EXECUTE SP_EXECUTESQL #SQL;
DECLARE #X NVARCHAR(MAX) = '[' + (SELECT * FROM ##T FOR XML PATH('')) + ']';
SELECT #X = REPLACE(#X, '<' + Name + '>',
CASE WHEN ROW_NUMBER() OVER(ORDER BY Column_ID) = 1 THEN '{'
ELSE '' END + Name + ':'),
#X = REPLACE(#X, '</' + Name + '>', ','),
#X = REPLACE(#X, ',{', '}, {'),
#X = REPLACE(#X, ',]', '}]')
FROM sys.columns
WHERE [Object_ID] = OBJECT_ID(#TableName)
ORDER BY Column_ID;
DROP TABLE ##T;
SELECT Json = #X;
END
Sample data:
CREATE TABLE [dbo].[Test1](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Col1] [int] NOT NULL,
[Col 2] varchar(50)
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Test1] ON
GO
INSERT [dbo].[Test1] ([ID], [Col1], [Col 2]) VALUES (1, 0,'ABCD')
GO
INSERT [dbo].[Test1] ([ID], [Col1] ,[Col 2]) VALUES (2, 1, 'POIU')
GO
SET IDENTITY_INSERT [dbo].[Test1] OFF
GO
You can use the following code:
Inside an APPLY, unpivot the columns as key/value pairs...
... and aggregate using FOR JSON PATH
Use STRING_AGG to do another aggregation.
SELECT '[' + STRING_AGG(CAST(v.json AS nvarchar(max)), ',') + ']'
FROM T
CROSS APPLY (
SELECT *
FROM (VALUES
('ID', CAST(ID AS nvarchar(100))),
('Name', Name),
('Program', Program),
('Type', [Type]),
('Section', Section),
('Director', Director),
('Project', Project),
('Sr Manager', [Sr Manager]),
('PCM', PCM),
('Contractor', Contractor),
('Cost Client', [Cost Client])
) v([key], value)
FOR JSON PATH
) v(json)
db<>fiddle
You cannot use FOR JSON again, because then you will get ["json": [{"key" : ...
first of all check this link you can find what you want
format-query-results-as-json-with-for-json-sql-server
but in your case you can try this
SELECT
ID,Name,Program,Type,Section,
Director,Project,Sr,Manager,PCM,Contractor,Cost,Client
FROM table
FOR JSON AUTO;
check the link there is more sample so it can help you

MySQL Replace String "John Doe" with "John D"

Have a large name table all as string "Name Surname"
Need to update the entire table, setting the string to be "Name FirstLetterOfSurname" ie. "John Citizen" becomes "John C".
Seems easier to do via PHP eg.
$name = "John Doe";
$expl = explode(' ', $name);
echo $expl [0].' '.$expl[1][0];
John D
wondering about a query to just update the database.
Help Appreciated?
I'd find the location of the space, and take a substring of one character more than that:
SELECT SUBSTR(name, 1, LOCATE(' ', name) + 1)
FROM mytable
Of course, this can also be done as an update instead of just querying the string in the right format:
UPDATE mytable
SET name = SUBSTR(name, 1, LOCATE(' ', name) + 1)
If you want to update the database, please use the following query:
UPDATE TestTable
SET FirstName = CONCAT(LEFT(FirstName, INSTR(FirstName, ' ')) , LEFT(SUBSTRING(FirstName, INSTR(FirstName, ' ') + 1), 1)) ;
Please find the Working Demo with sample data.

SSRS. Extra space between FirstName and LastName

I have report that displays name (FirstName MiddleName LastName). Each field has a space between and works great when name has MiddleName. However, when MiddleName is NULL, space renders between FirstName and LastName. What is the best way to solve that problem?
I tried something like that:
=Fields!FirstName.Value & "" & iif (isNothing(Fields!MiddleName.Value), "", Fields!MiddleName.Value) & "" & Fields!LastName.Value
With your current expression there should be no spaces. If there are any spaces currently they must exist in your database... This can be confirmed by using TRIM on FirstName, MiddleName, LastName.
To properly format your string you need to use spaces between the "", and ensure the space following the middle name is contained within the iif statement
=TRIM(Fields!FirstName.Value) & " " &
iif (isNothing(TRIM(Fields!MiddleName.Value)),
"",
TRIM(Fields!MiddleName.Value) & " ")
& TRIM(Fields!LastName.Value)
Firstly your expression above doesn't returns a name with space.
I think you mean something like this with space:
=Fields!FirstName.Value & " " & iif (isNothing(Fields!MiddleName.Value), " ", Fields!MiddleName.Value) & " " & Fields!LastName.Value
Aside from Jonnus answer you could also use 'Len' to check its length.
If you only worry about the MiddleName you could use this expression using Len
=Fields!FirstName.Value & " " & IIF(Len(Fields!MiddleName.Value) < 1,"", Fields!MiddleName.Value) & " " & Fields!LastName.Value
But if I were you I would rather use sql function to handle this rather than do it in expression which is messy. And I could also reuse this for other reports than repeat the expression again.
Here is an example of function that returns a fullname with middle name of your format.
IF EXISTS (
SELECT *
FROM dbo.sysobjects
WHERE ID = OBJECT_ID(N'[dbo].[GetClientFullNameWithMiddleName]') AND
xtype in (N'FN', N'IF', N'TF'))
DROP FUNCTION [dbo].[GetClientFullNameWithMiddleName]
GO
CREATE FUNCTION [dbo].[GetClientFullNameWithMiddleName](#ClientID UNIQUEIDENTIFIER)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #FULLNAME NVARCHAR(MAX)
DECLARE #LASTNAME NVARCHAR(MAX)
DECLARE #FIRSTNAME NVARCHAR(MAX)
DECLARE #MIDDLENAME NVARCHAR(MAX)
SET #LASTNAME = ISNULL((SELECT Lastname FROM Client WHERE ClientID = #ClientID),'')
SET #FIRSTNAME = ISNULL((SELECT Firstname FROM Client WHERE ClientID = #ClientID),'')
SET #MIDDLENAME = ISNULL((SELECT Middlename FROM Client WHERE ClientID = #ClientID),'')
IF(#ClientID <> '00000000-0000-0000-0000-000000000000')
BEGIN
IF(#FIRSTNAME <> '')
BEGIN
SET #FULLNAME = CAST((#FIRSTNAME) AS NVARCHAR(MAX))
IF(#MIDDLENAME <> '' AND #FULLNAME <> '')
BEGIN
SET #FULLNAME = CAST((#FULLNAME + ' ' + #MIDDLENAME) AS NVARCHAR(MAX))
END
IF(#LASTNAME <> '' AND #FULLNAME <> '')
BEGIN
SET #FULLNAME = CAST((#FULLNAME + ' ' + #LASTNAME) AS NVARCHAR(MAX))
END
END
ELSE
BEGIN
SET #FULLNAME = CAST((#FIRSTNAME)AS NVARCHAR(MAX))
END
END
ELSE
BEGIN
SET #FULLNAME = ''
END
RETURN #FULLNAME
END
GO
Then you could use it like this
SELECT
[dbo].[GetClientFullNameWithMiddleInitial](ClientID)
FROM Client

Extracting Number From String SQL

I have a normal SQL statement:
SELECT VALUE_ID, UF_CRM_TASK FROM b_uts_tasks_task
Now this returns a a different field everytime but they take the form of the following:
a:1:{i:0;s:7:"CO_2012";} or a:1:{i:0;s:5:"CO_12";} or a:1:{i:0;s:7:"CO_2017";}
Basically they're different everytime. What I need is to just get the number after the CO_ part. I have tried TRIM but because everything changes in the leading and trailing section I don't think this would work.
I have looked on Stack Overflow for a while and cannot find it. I know how to do it in PHP:
$data = $row['UF_CRM_TASK'];
$companyID = substr($data, strpos($data, "CO_") + 1);
$newCompanyID = preg_replace('/[^0-9.]+/', '', $companyID);
But not SQL. Thanks in advance
In MYSQL is a bit ugly:
/*SUBSTRING_INDEX BASED ON CO_ AND THE LAST " - in 2 SUBSTRINGS*/
SELECT `VALUE_ID`, SUBSTRING_INDEX(SUBSTRING_INDEX(`UF_CRM_TASK`, 'CO_', -1), '"', 1) AS `COMPANY_ID` FROM `b_uts_tasks_task`
In PHP you can just unserialize():
$data = unserialize($row['UF_CRM_TASK']);
$companyID = str_replace('CO_', '', $data[0]);
eg:
$data = unserialize('a:1:{i:0;s:5:"CO_12";}');
echo str_replace('CO_', '', $data[0]);
//==> 12
You need to use CharIndex and SubString (Microsoft SQL) or
This is the sample code I made for my Microsoft SQL server:
declare #companyIdString varchar(50) = 'a:1:{i:0;s:7:"CO_2012";}'
print 'Company ID in a string: ' + #companyIdString
print 'Find first position: ' + Cast(charindex('"CO_', #companyIdString) as varchar(2))
print 'Locate the second position (the last "): ' + Cast(charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) as varchar(2))
print 'Extracted Company Id: ' + substring(#companyIdString,charindex('"CO_', #companyIdString)+4, charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) - charindex('"CO_', #companyIdString) - 4)
select
#companyIdString as CompanyIdString,
substring(#companyIdString,charindex('"CO_', #companyIdString)+4, charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) - charindex('"CO_', #companyIdString) - 4) as CompanyId
I also made the same code on a mySQL server:
set #companyIdString := 'a:1:{i:0;s:7:"CO_2012";}';
select
#companyIdString as CompanyIdString,
substring_index(substring_index(substring_index(#companyIdString, '"', 2), '"', -1), '_', -1) as CompanyId
The substring_index starts by locating the second " (string is now a:1:{i:0;s:7:"CO_2012), then it searches backward with the -1 to locate the first " (string is now CO_2012). And then it searches backward for the underscore (string is now 2012).

Parameterizing an SQL query which uses the NOT LIKE, " ^ " wildcard?

How can I parameterize the following query? (By the way I'm using a full text indexed table, hence the CONTAINS())
SELECT * FROM Table WHERE CONTAINS(Column, 'cat OR dog')
and ((column NOT LIKE '%[^ cat OR dog]%'));
This didn't work:
DECLARE #term1 VARCHAR(10);
DECLARE #term2 VARCHAR(10);
SET #term1 = 'cat';
SET #term2 = 'dog';
SET #term3 = #term1 + ' ' + 'OR' + ' ' + #term2;
SET #term4 = '[^ #term1 OR #term2 ]' ;
SELECT * FROM table WHERE CONTAINS(column, #term3) <--up to this point works
AND (column NOT LIKE '%[#term4]%'); <--this part doesn't include the second term (#term2)
If you'd like to fiddle with this on your end, my Full Text Indexed table looks like:
animalListID AnimalsList
1 cat dog
2 cat
3 cat dog bird
(basically i need the parameterized version of the SELECT statement which returns the rows with 'cat dog' and 'cat' and NOT 'cat dog bird')
**This is a VERY oversimplified version of my data, but the question is an exact match of the concept I'm trying to achieve. The table will have millions of rows, and many terms in each row.
You should do
SET #term4 = '[^ ' + #term1 + ' OR ' + #term2 + ' ]';
and
column NOT LIKE '%' + #term4 + '%'
Alternatively, you could initialize #term4 to also include the % signs:
SET #term4 = '%[^ ' + #term1 + ' OR ' + #term2 + ' ]%';
and then simplify the LIKE statement to:
column NOT LIKE #term4