Concatenating Values in SQL Server using a CTE - sql

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

Related

Concatenating columns in SQL with delimiter. If first column is null, do not want delimiter to show up after it. How do I get rid of that?

SELECT TOP 1000 places.*
, home_Desc
, CONCAT_WS(' - ', COALESCE(brand, ' '), home_Desc, location_Desc) AS homeSite
Example:
brand
home_Desc
location_Desc
blue
large
woody
NULL
small
forest
So right now I am getting:
1.' blue - large - woody '
2. ' - small - forest '
But what I want for the second set is:
small - forest
CREATE TABLE TEST(brand VARCHAR(100), home_Desc VARCHAR(100), location_Desc VARCHAR(100))
INSERT INTO TEST VALUES ('blue','large','woody'),
(NULL,'small','forest')
SELECT CONCAT_WS(' - ',brand, home_Desc, location_Desc) FROM TEST
As Squirrel say, you must replace COALESCE(brand, '') to brand
Taking advantage of the rule a non-NULL value (the dash character in this instance) concatenated with a NULL value (branch, in this instance) would yield NULL (and assuming that the other two can never be null/blank:
, COALESCE(brand + '-', ' ') + home_Desc + ' - ' + location_Desc AS homeSite

Using ISNULL does not produce the expected results

I am trying to concatenate several columns of a person's name into one column and ultimately into a temporary table. I am unable to get the ISNULL function to work correctly.
I have tried using ISNULL to effectively say "if this column is blank, then just ignore it". I've read about a command called ISBLANK but that doesn't seem to work on my version of SQL Server.
SELECT
co.serialnumber, co.envelopesalutation,
co.title + ' ' + LEFT(co.firstname, 1) + ' ' + ISNULL(LEFT(co.otherinitial, 1), '') +
' ' + co.keyname + ' ' + ISNULL(co.POSTNOMINAL, '') [Correct]
INTO
TEMPENVSALUTATION
FROM
contact co
WHERE
co.contacttype = 'Individual'
AND co.title IN ('Mr', 'Mrs', 'Ms', 'Miss', 'Mx', 'Dr')
I expect, for example, that someone with co.title of Mr, a co.firstname of Jon, no co.otherinitial a co.keyname of Smith and no co.postnominal to appear in the TEMPENVSALUTATION table as Mr J Smith
What I'm actually getting is only people who have a co.otherinitial appearing e.g. Mr S D Smith.

SELECT DISTINCT is omitting NULL values when not desired

I am trying to build a distinct string in a query, which works unless one of the values is NULL. I've tested removing LOCATION_ADDR_LINE_2, and the query will work just fine. When I do not SELECT DISTINCT, I find that LOCATION_ADDR_LINE_2 values are NULL. How can I gather these values in the SELECT DISTINCT even if NULL?
SELECT DISTINCT(LOCATION_ADDR_LINE_1 + ', ' + LOCATION_ADDR_LINE_2 + ', ' + LOCATION_CITY + ', ' + LOCATION_WORK_STATE) AS Addresses
FROM OracleReport
WHERE (LOCATION_ADDR_LINE_1 LIKE '%1135 Auto%' OR LOCATION_ADDR_LINE_1 LIKE '%199 Easy%')
Returns:
Addresses
NULL
SELECT DISTINCT(LOCATION_ADDR_LINE_1 + ', ' + LOCATION_CITY + ', ' + LOCATION_WORK_STATE) AS Addresses
FROM [OperationReport].[dbo].[OracleReport]
WHERE (LOCATION_ADDR_LINE_1 LIKE '%1135 Auto%' OR LOCATION_ADDR_LINE_1 LIKE '%199 Easy%')
Returns:
Addresses
1135 Auto...
189-199 Easy...
Assuming you don't mind text,,text,... (empty string) when a value is NULL...
SELECT DISTINCT(coalesce(LOCATION_ADDR_LINE_1,'') + ', ' +
coalesce(LOCATION_ADDR_LINE_2,'') + ', ' +
coalesce(LOCATION_CITY,'') + ', ' +
coalesce(LOCATION_WORK_STATE,'')) AS Addresses
FROM OracleReport
WHERE (LOCATION_ADDR_LINE_1 LIKE '%1135 Auto%'
OR LOCATION_ADDR_LINE_1 LIKE '%199 Easy%')
Coalesce will take the first non-null value and return it. It requires consistent data types and will early exit once the first non-null value in a series is encountered. (more details Oracle Differences between NVL and Coalesce)

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,

Using XML PATH in Sql Stored Procedure

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?