Using XML PATH in Sql Stored Procedure - sql

I'm trying to get a row with the concatenation of a welders names.
This is what i've got:
SELECT jsd1.JuntaSoldaduraID,
REPLACE(RTRIM((SELECT s1.Nombre + ' ' + s1.ApPaterno + ' ' +
s1.ApMaterno + '' + CAST('' AS VARCHAR(MAX)) + ' '
FROM JuntaSoldaduraDetalle jsd
INNER JOIN Soldador s1 on s1.SoldadorID = jsd.SoldadorID
WHERE (jsd1.JuntaSoldaduraID = jsd.JuntaSoldaduraID)
and (jsd.TecnicaSoldadorID = 2)
FOR XML PATH (''))),' ',', ') AS NombreSoldador
FROM JuntaSoldaduraDetalle jsd1
INNER JOIN Soldador s
ON s.SoldadorID = jsd1.SoldadorID
GROUP BY jsd1.JuntaSoldaduraID
I'm able to get the information that i want but with a little problem.
What I want is "John Smith, David Rogers, Peter Simons" etc.. in other words, full names separated by commas.
But i'm receiving "John, smith, David, Rogers, Peter, Simons"..
Any help appreciated.
Thanks in advance.

Your REPLACE will replace all spaces with a comma. Instead, make the comma part of your query and use STUFF to remove the first occurrence of the comma. You might also want to incorporate the use of COALESCE in case any of the name fields are NULL.
SELECT jsd1.JuntaSoldaduraID,
STUFF((SELECT ', ' + COALESCE(s1.Nombre + ' ','')
+ COALESCE(s1.ApPaterno + ' ','')
+ COALESCE(s1.ApMaterno,'')
FROM JuntaSoldaduraDetalle jsd
INNER JOIN Soldador s1
on s1.SoldadorID = jsd.SoldadorID
WHERE jsd1.JuntaSoldaduraID = jsd.JuntaSoldaduraID
and jsd.TecnicaSoldadorID = 2
FOR XML PATH ('')),1,2,'') AS NombreSoldador
FROM JuntaSoldaduraDetalle jsd1
INNER JOIN Soldador s
ON s.SoldadorID = jsd1.SoldadorID
GROUP BY jsd1.JuntaSoldaduraID

You are replacing single spaces in the result with a comma and a space.
What is the result if you remove the REPLACE from the query?

Related

Filter rows by whether a text column contains any words in a string in SQL

My SQL Server database table has a column text which is a long string of text.
The search list is a string of words separated by comma. I want to grab those rows where the text column contains any one of words in the string.
DECLARE #words_to_search nvarchar(50)
SET #words_to_search = 'apple, pear, orange'
SELECT *
FROM myTbl
WHERE text ??? --how to specify text contains #words_to_search
Thanks a lot in advance.
If you're running SQL Server 2016 or later, you can use STRING_SPLIT to convert the words to search into a single column table, and then JOIN that to your table using LIKE:
DECLARE #words_to_search nvarchar(50)
SET #words_to_search = 'apple,pear,orange'
SELECT *
FROM myTbl
JOIN STRING_SPLIT(#words_to_search, ',') ON text LIKE '%' + value + '%';
Demo on SQLFiddle
Note that as the query is written it will (for example) match apple within Snapple. You can work around that by making the JOIN condition a bit more complex:
SELECT *
FROM myTbl t
JOIN STRING_SPLIT(#words_to_search, ',') v
ON t.text LIKE '%[^A-Za-z]' + value + '[^A-Za-z]%'
OR t.text LIKE value + '[^A-Za-z]%'
OR t.text LIKE '%[^A-Za-z]' + value;
Demo on SQLFiddle
First, I would use exists, unless you want to return the matching word.
Second, you can do this with a single like comparison If words are separated by spaces:
select t.*
from t
where exists (select 1
from string_split(#words_to_search, ',') s
where ' ' + t.text + ' ' like '% ' + value + ' %'
);
For more generic separators, you can use:
select t.*
from t
where exists (select 1
from string_split(#words_to_search, ',') s
where ' ' + t.text + ' ' like '%[^A-Za-z]' + value + '[^A-Za-z]%'
);
Or whatever describes your separators.
Note that your list of words is separated by a comma-space, not just a comma. However, based on your description (not the sample data), I have only used a ',' for the separator.

SQL subtracting a string column from another string column

I am looking to subtract two string columns from another string column.
I have acheived this in the past in Oracle using the below
SELECT
C.MANUFACTURER,
C.MODEL_GROUP,
REGEXP_REPLACE(C.VARIANT, '^'||C.MANUFACTURER || ' +' || C.MODEL_GROUP) "VAR DESC",
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C
I now need to acheive the same in MS SQL any suggestions would be appreciated.
"Subtract" is surely a misnomer here. The OP appears to want to remove a string at the beginning of another string.
From this point on, I am assuming that MANUFACTURER and MODEL_GROUP do not contain any regular expression wildcard characters.
There is a challenge with multiple spaces. If there are not too many, then you can do. For instance, this handles one or two spaces:
SELECT C.MANUFACTURER, C.MODEL_GROUP,
(CASE WHEN C.VARIANT LIKE C.MANUFACTURER + ' ' + C.MODEL_GROUP + '%'
THEN STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER + ' ' + C.MODEL_GROUP), '')
WHEN C.VARIANT LIKE C.MANUFACTURER + ' ' + C.MODEL_GROUP + '%' AND
THEN STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER + ' ' + C.MODEL_GROUP), '')
ELSE C.VARIANT
END) as [VAR DESC],
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C;
EDIT:
Here is a more complete solution:
SELECT C.MANUFACTURER, C.MODEL_GROUP,
(CASE WHEN C.VARIANT LIKE C.MANUFACTURER + ' %' + C.MODEL_GROUP + '%' AND
C.VARIANT NOT LIKE C.MANUFACTURER + ' %[^ ]%' + C.MODEL_GROUP + '%'
THEN STUFF(LTRIM(STUFF(C.VARIANT, 1, LEN(C.MANUFACTURER), '')), 1, LEN(C.MODEL_GROUP), '')
ELSE C.VARIANT
END) as [VAR DESC],
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C;
This tests for just spaces between the two strings (the not like is checking for something other than a space). The replacement is then in three steps -- remove the manufacturer, then the spaces, then the model group.
I have spent some time on this one as much for my own satisfaction and in addition to the answer above, I have come up with the following which also generates the correct answer.
SUBSTRING(FV.VARIANT, LEN(FV.MANUFACTURER + ' ' + FV.MODEL_RANGE + ' ') + 1 , LEN(FV.VARIANT))
My problem was kinda easier to solve, I just needed to remove "xxxx" (the first 4 characters) at the start of a column from some rows:
UPDATE coluna SET columToEdit = SUBSTRING(columToEdit, 5, 200);

Concatenating Values in SQL Server using a CTE

I have been trying to concatenate values for a particular row. Say I have a query:
SELECT
tblContacts_2.contactid,
(COALESCE (tblSites_1.sitenm, '')
+ COALESCE (' / ' + tblSites_1.sitenmalt, '')
+ ' ' + COALESCE (tblSites_1.addr1, '') + ' '
+ COALESCE (tblSites_1.zipcodeid, '') ) AS SiteNameAddr,
tblSites_1.siteid
FROM
dbo.tblcontacts AS tblContacts_2
INNER JOIN
dbo.tjncsitecontacts AS tjncSiteContacts_1 ON tblContacts_2.contactid = tjncSiteContacts_1.contactid
INNER JOIN
dbo.tblsites AS tblSites_1 ON tblSites_1.siteid = tjncSiteContacts_1.siteid
The output for this is
ContactID SiteNameAddr SiteID
--------------------------------------------------------------
329 TWIN PARKS SOUTHWEST / TWIN PARKS SOUTH... 1
1788 TWIN PARKS SOUTHWEST / TWIN PARKS S.... 1
What I want is, an output of this format where the sitenameaddrs for one contact id is concatenated like below with a count of site ids it is associated with:
ContactID SiteNameAddr CountSite
-----------------------------------------------------------------------
321 RIVERSIDE PARK / 3333 BROADWAY 10035, URBAN... 8
322 WESTVIEW 625 MAIN ST 10044 1
The problem is, the following code fails while doing this -
SELECT
tblContacts_2.contactid,
dbo.Removelastchar(dbo.Strconcat(COALESCE (tblSites_1.sitenm, '')
+ COALESCE (' / ' +
tblSites_1.sitenmalt, '')
+ ' ' + COALESCE (tblSites_1.addr1, '')
+ ' '
+ COALESCE (tblSites_1.zipcodeid, '') +
', '))
AS SiteNameAddr,
Count(tblSites_1.siteid) AS CountSite
FROM
dbo.tblcontacts AS tblContacts_2
INNER JOIN
dbo.tjncsitecontacts AS tjncSiteContacts_1 ON tblContacts_2.contactid = tjncSiteContacts_1.contactid
INNER JOIN
dbo.tblsites AS tblSites_1 ON tblSites_1.siteid = tjncSiteContacts_1.siteid
GROUP BY
tblContacts_2.contactid
Error:
A .NET Framework error occurred during execution of user-defined
routine or aggregate "strconcat":
System.Data.SqlServer.TruncationException: Trying to convert return
value or output parameter of size 8086 bytes to a T-SQL type with a
smaller size limit of 8000 bytes.
This is because one of the contact ids has 92 sites associated with it and the concatenated string becomes too large. Also, dbo.Removelastchar and dbo.Strconcat are scalar functions so they can only return nvarchar and hence can't use ntext in them. Type-casting of data-type is not working either.
Please let me know what is the alternative to this. The concatenated string is picked up by VBA code in Access

TSQL get data regardless of Null value

I have a stored procedure that is getting information from my employee table and returning the data.
There are 3 columns that are used:
B.[SiloDesc] + ' (' + B.[TitleDesc] + ') ' + B.[SkillSetDesc] as SkillSetDesc,
My issue is, if one of those happens to be null, it wont display any of the data. What is the best way to have it include the data regardless of if one of those fields are null.
You could use coalesce() or isnull() for each individual column... or you could simply use...
CONCAT ( string_value1, string_value2 [, string_valueN ] )
Takes a variable number of string arguments and concatenates them into a single string. It requires a minimum of two input values; otherwise, an error is raised. All arguments are implicitly converted to string types and then concatenated. Null values are implicitly converted to an empty string.
A.: Remove the parentheses when TitleDesc is null:
select concat(B.[SiloDesc], ' (' + B.[TitleDesc] + ')', ' ' + B.[SkillSetDesc])
Because of the way null is treated in sql, the expression ' (' + null + ')' results in null which concat() will treat as an empty string... which is kind of nice as it effectively removes the parentheses if the value is null.
B.: Keep the parentheses regardless:
select concat(B.[SiloDesc], ' (', B.[TitleDesc], ') ', B.[SkillSetDesc])
Samples:
select concat('john', ' (' + null + ')', ' adams') -- john adams
select concat('john', ' (test)', ' ' + null) -- john (test)
select concat('john', ' (the man)', ' adams') -- john (the man) adams
isnull(B.[SiloDesc], '')
+ ' (' + isnull(B.[TitleDesc], '') + ') '
+ isnull(B.[SkillSetDesc], '') as SkillSetDesc,

String Concatenation with comma

I am trying to build the string with comma but I get extra space. How can I remove extra space between zipcode and country_name? Here is my string. Thank you for any suggestion.
SELECT
(COALESCE(address + ', ', '') +
COALESCE(city + ', ', '') +
COALESCE(state_code + ' ', '') +
COALESCE(zipcode + ' ', '') +
COALESCE(country_name + '', '')) address
from table1
where a_id = 2
Here is the result:
tewt, test ct, DE 4444 United States
You can use the RTRIM function which remove white space from right side of the variable. Check also LTRIM for the left cases.
I would change table column datatape to varchar(x) from char(x) or to nvarchar(x) from nchar(x). And change the data so they dont contain spaces. Just have to do that once and make changes so that app is not storing white spaces anymore.
char(x) and nchar(x) i would use just when there is fixed length strings, but this does not seem to be the case.