SQL Server T-SQL not returning results with no error - this should work right? - sql

I am trying to find something that does not match in 2 tables, this should be easy, now this works fine.
Select *
from Shop_Import SI
where SI.productID not in (SELECT productref FROM Shop_Import_Cats)
But this is the SQL I need to use, but it just does not return the 1 result that the above does:
SELECT
'Insert into Shop_Import_Cats values ('
+ CAST(p.ProductID AS VARCHAR) + ','
+ CAST(c.CategoryID AS VARCHAR) + ','
+ CAST(SI.ProductID AS VARCHAR) + ',getdate())
FROM
NB_Store_Products p
JOIN
NB_Store_ProductLang pl ON p.ProductID = pl.ProductID
JOIN
Shop_Import SI ON p.ProductRef = SI.ProductID
JOIN
NB_Store_CategoryLang CL ON SI.Primary_Category = CL.CategoryName
JOIN
NB_Store_Categories C ON CL.CategoryID = C.CategoryID
JOIN
Shop_Import_Cats SIC ON SI.ProductID = SIC.productref
WHERE
SI.ProductID NOT IN (SELECT SIC.productref
FROM Shop_Import_Cats SIC)
Based on advice here I tried this swapping the tables around and left joins to no avail - it returns null but should return one result.
Select 'Insert into Shop_Import_Cats values (' + CAST(p.ProductID as varchar) + ',' + CAST(c.CategoryID as varchar) + ',' + CAST(SI.ProductID as varchar) + ',getdate())'
from Shop_Import SI
left join NB_Store_Products P on SI.ProductID=p.ProductRef
left join NB_Store_ProductLang pl on p.ProductID=pl.ProductID
left join NB_Store_CategoryLang CL on SI.Primary_Category=CL.CategoryName
left join NB_Store_Categories C on CL.CategoryID=C.CategoryID
left join Shop_Import_Cats SIC on SI.ProductID=SIC.productref
where SI.ProductID not in (SELECT SIC.productref FROM Shop_Import_Cats SIC)
What am I doing wrong?

Try this instead:
SELECT
'Insert into Shop_Import_Cats values ('
+ CAST(coalesce(p.ProductID,' ') AS VARCHAR) + ','
+ CAST(coalesce(c.CategoryID,' ') AS VARCHAR) + ','
+ CAST(coalesce(SI.ProductID,' ') AS VARCHAR) + ',getdate())
from (
select
ProductID,
Primary_Category
/* insert any additional required columnx here */
from Shop_Import SI
where SI.ProductID not in (SELECT SIC.productref FROM Shop_Import_Cats SIC)
) SI
left join NB_Store_Products P on SI.ProductID = p.ProductRef
left join NB_Store_ProductLang pl on p.ProductID = pl.ProductID
left join NB_Store_CategoryLang CL on SI.Primary_Category = CL.CategoryName
left join NB_Store_Categories C on CL.CategoryID = C.CategoryID
left join Shop_Import_Cats SIC on SI.ProductID = SIC.productref
Now the WHERE condition will be executed on the same relvar as in the working example. I suspect that a null value is invoking 3-valued logic and propagating an UNKNOWN into a null record-set.
** edit Needed to add the SI to the 'from Shop_Import'

You just need to remove Shop_import_cats from the join:
Select 'Insert into Shop_Import_Cats values (' + CAST(p.ProductID as varchar) + ',' + CAST(c.CategoryID as varchar) + ',' + CAST(SI.ProductID as varchar) + ',getdate())'
from Shop_Import SI
left join NB_Store_Products P on SI.ProductID=p.ProductRef
left join NB_Store_ProductLang pl on p.ProductID=pl.ProductID
left join NB_Store_CategoryLang CL on SI.Primary_Category=CL.CategoryName
left join NB_Store_Categories C on CL.CategoryID=C.CategoryID
where SI.ProductID not in (SELECT SIC.productref FROM Shop_Import_Cats SIC)

Related

Left join with view taking too much time in SQL Server

This query is taking twenty seconds to display 53,000 records. This query has five left joins with views. But when I comment out the column MAN.F_PHR AS MANU in the select statement, it takes three seconds to display the 53,000 records.
How can I optimize this query? The view V_PROD_ALIAS_MANU MAN contains two left joins. The MAN.F_PHRE AS MANU column is from the view. Is there any way to optimize this query?
SELECT DISTINCT
TP.PRODUCT AS ID,
TP.NAME AS [NAME],
TP.LANGUAGE AS LANGCODE,
CONVERT(VARCHAR,TP.F_DATE_REVISED,120) AS RDATE,
CASE
WHEN NOT(REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUM,'¿',' '))),' ','; ') IS NULL OR REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUM,'¿',' '))),' ','; ') = '')
THEN REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUM,'¿',' '))),' ','; ')
ELSE REPLACE(LTRIM(RTRIM(REPLACE(CASN.F_DATA,'¿',' '))),' ','; ')
END AS CASNUM ,
TP.F_CUSTOM1 AS cus1,
TP.F_CUSTOM2 AS cus2,
(SELECT TC.F_COUNTRY_NAME FROM COUNTRIES TC
WHERE TC.F_COUNTRY_CODE = TP.F_CUSTOM5) AS cus5,
MAN.F_PHR AS MANU,
CASE
WHEN NOT(TP.F_CUSTOM3 IS NULL OR TP.F_CUSTOM3 = '')
THEN TP.F_CUSTOM3
ELSE SYN.F_DATA
END AS SYN,
IC.F_DATA AS ICO,
'SDS - ' + (SELECT TL.F_LAN_NAME FROM T_LANGUAGE TL
WHERE TL.F_LANGUAGE = TP.F_LANGUAGE) + ' - PDF' AS DOC,
'' AS COVER,
CAST(TP.F_GUID AS VARCHAR(36)) + '_PDF' AS [GUID],
'PDF' AS SDS
FROM
PDF TP
LEFT JOIN
V_PROD_ALIAS_SYN SYN ON TP.F_PRODUCT = SYN.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_SITE SIT ON TP.F_PRODUCT = SIT.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_ICO IC ON TP.F_PRODUCT = IC.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_MANU MAN ON TP.F_PRODUCT = MAN.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_CASN CASN ON TP.F_PRODUCT = CASN.F_PRODUCT
Query after commenting out the column MAN.F_PHRE AS MANU takes three seconds to display 53,000 records.
SELECT DISTINCT
TP.PRODUCT AS ID,
TP.NAME AS [NAME],
TP.LANGUAGE AS LANGCODE,
CONVERT(VARCHAR, TP.F_DATE_REVISED, 120) AS RDATE,
CASE
WHEN NOT(REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUM,'¿',' '))),' ','; ') IS NULL OR REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUM,'¿',' '))),' ','; ') = '')
THEN REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUM,'¿',' '))),' ','; ')
ELSE REPLACE(LTRIM(RTRIM(REPLACE(CASN.F_DATA,'¿',' '))),' ','; ')
END AS CASNUM ,
TP.F_CUSTOM1 AS cus1,
TP.F_CUSTOM2 AS cus2,
(SELECT TC.F_COUNTRY_NAME FROM COUNTRIES TC
WHERE TC.F_COUNTRY_CODE = TP.F_CUSTOM5) AS cus5,
-- MAN.F_PHR AS MANU,
CASE
WHEN NOT(TP.F_CUSTOM3 IS NULL OR TP.F_CUSTOM3 = '')
THEN TP.F_CUSTOM3
ELSE SYN.F_DATA
END AS SYN,
IC.F_DATA AS ICO,
'SDS - ' + (SELECT TL.F_LAN_NAME FROM T_LANGUAGE TL
WHERE TL.F_LANGUAGE = TP.F_LANGUAGE) + ' - PDF' AS DOC,
'' AS COVER,
CAST(TP.F_GUID AS VARCHAR(36)) + '_PDF' AS [GUID],
'PDF' AS SDS
FROM
PDF TP
LEFT JOIN
V_PROD_ALIAS_SYN SYN ON TP.F_PRODUCT = SYN.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_SITE SIT ON TP.F_PRODUCT = SIT.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_ICO IC ON TP.F_PRODUCT = IC.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_MANU MAN ON TP.F_PRODUCT = MAN.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_CASN CASN ON TP.F_PRODUCT = CASN.F_PRODUCT

How to merge two queries into one

How can I join these 2 SQL statements? I want the columns of the first and the columns of the second to appear together as one SQL query.
SELECT
E.tbl1_ORG AS Organización, E.tbl1_CODE AS [Orden de Trabajo],
E.tbl1_OBJECT AS Equipo, O.tbl3_POSITION AS Posicion,
E.tbl1_JOBTYPE AS [Tipo de Trabajo],
E.tbl1_DESC AS [Descripcion OT], E.tbl1_WORKADDRESS AS Comentarios,
E.tbl1_REQM AS Error, B.tbl2_PERSON AS Trabajador,
B.tbl2_ENTERED AS Fecha, B.tbl2_HOURS AS Horas
FROM
dbo.table1 AS E
INNER JOIN
dbo.table2 AS B ON E.tbl1_CODE = B.tbl2_EVENT
INNER JOIN
dbo.table3 AS O ON O.tbl3_CODE = E.tbl1_OBJECT
WHERE
E.tbl1_JOBTYPE IN ('PM', 'CM', 'PMM') and
E.tbl1_ORG = #PROMPT('Organización')# and
B.tbl2_ENTERED between #PROMPT('Fecha_Inicio')# and #PROMPT('Fecha_Final')# and
(E.tbl1_REQM = #PROMPT('Error')# OR #PROMPT('Error')# = '%') and
(E.tbl1_OBJECT = #PROMPT('Equipo')# OR #PROMPT('Equipo')# = '%') and
(O.tbl3_POSITION = #PROMPT('Posicion')# OR #PROMPT('Posicion')# = '%')
And:
SELECT
tbl2_event 'Orden de Trabajo',
STUFF((SELECT ', ' + CAST(tbl2_person AS VARCHAR(100)) [text()]
FROM table2
WHERE tbl2_event = t.tbl2_event
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,1,' ') Empleados,
STUFF((SELECT ', ' + CAST(tbl2_hours AS VARCHAR(100)) [text()]
FROM table2
WHERE tbl2_event = t.tbl2_event
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'), 1, 1, ' ') Horas
FROM table2 t
GROUP BY tbl2_event
Both work perfectly on their own, but I don't know how to merge them.
Add ROW_NUMBER to each query and then FULL JOIN them together. You'll need to decide on the ordering of rows in each query.
WITH
CTE1
AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY ...) AS rn,
E.tbl1_ORG AS Organización, E.tbl1_CODE AS [Orden de Trabajo],
E.tbl1_OBJECT AS Equipo, O.tbl3_POSITION AS Posicion,
E.tbl1_JOBTYPE AS [Tipo de Trabajo],
E.tbl1_DESC AS [Descripcion OT], E.tbl1_WORKADDRESS AS Comentarios,
E.tbl1_REQM AS Error, B.tbl2_PERSON AS Trabajador,
B.tbl2_ENTERED AS Fecha, B.tbl2_HOURS AS Horas
FROM
dbo.table1 AS E
INNER JOIN
dbo.table2 AS B ON E.tbl1_CODE = B.tbl2_EVENT
INNER JOIN
dbo.table3 AS O ON O.tbl3_CODE = E.tbl1_OBJECT
WHERE
E.tbl1_JOBTYPE IN ('PM', 'CM', 'PMM') and
E.tbl1_ORG = #PROMPT('Organización')# and
B.tbl2_ENTERED between #PROMPT('Fecha_Inicio')# and #PROMPT('Fecha_Final')# and
(E.tbl1_REQM = #PROMPT('Error')# OR #PROMPT('Error')# = '%') and
(E.tbl1_OBJECT = #PROMPT('Equipo')# OR #PROMPT('Equipo')# = '%') and
(O.tbl3_POSITION = #PROMPT('Posicion')# OR #PROMPT('Posicion')# = '%')
)
,CTE2
AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY ...) AS rn,
tbl2_event 'Orden de Trabajo',
STUFF((SELECT ', ' + CAST(tbl2_person AS VARCHAR(100)) [text()]
FROM table2
WHERE tbl2_event = t.tbl2_event
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,1,' ') Empleados,
STUFF((SELECT ', ' + CAST(tbl2_hours AS VARCHAR(100)) [text()]
FROM table2
WHERE tbl2_event = t.tbl2_event
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'), 1, 1, ' ') Horas
FROM table2 t
GROUP BY tbl2_event
)
SELECT ...
FROM
CTE1 FULL JOIN CTE2 ON CTE1.rn = CTE2.rn
ORDER BY ...
;
If you have more than 2-3 tables to join like this FULL JOIN would quickly become ugly and slow. Have a look at my answer for a similar question for alternative solution: best way to "glue" columns together

Pivot table giving wrong result

Below code gives me result set as shown in first image
SELECT dbo.tbStudent.Name, dbo.tbStudent.RegNo, dbo.tbFee.PID, dbo.tbFee.Purpose, dbo.tbFee.AmountPaid, dbo.tbFee.StudentID, dbo.tbFee.Date, dbo.tbFee.FeeID,
dbo.tbFee.SemID, dbo.tbFee.CourseID, dbo.tbFee.ModeOfPayment, dbo.tbFee.CheckNo, dbo.tbFee.DDNo, dbo.tbFee.HostelDDNo, dbo.tbFee.FRID,
dbo.tbStudent.Parentage, dbo.tbCourse.Name AS Course, ISNULL(dbo.tbSemester.SemName, ' + #st +') AS Semester
FROM dbo.tbFee INNER JOIN
dbo.tbStudent ON dbo.tbFee.StudentID = dbo.tbStudent.StudentID INNER JOIN
dbo.tbCourse ON dbo.tbFee.CourseID = dbo.tbCourse.CourseID LEFT OUTER JOIN
dbo.tbSemester ON dbo.tbFee.SemID = dbo.tbSemester.SemID Where tbFee.SemID=1
However using Pivot table I need result as below:
My code for pivot table is :
SET #values = '';
If(#SemID=0)
BEGIN
SELECT #values = #values +'['+ CAST(PurPose AS varchar(max))+ ']' + ','
FROM tbFee Where CourseID=#CourseID
SET #values = SUBSTRING(#values, 1, Len(#values) - 1)
END
ELSE
BEGIN
SELECT #values = #values +'['+ CAST(PurPose AS varchar(max))+ ']' + ','
FROM tbFee Where SemID=#SemID
SET #values = SUBSTRING(#values, 1, Len(#values) - 1)
END
Declare #st nvarchar(max)
set #st='''Not Available''';
declare #q nvarchar(max)
set #q = '
Select * from(
SELECT dbo.tbStudent.Name, dbo.tbStudent.RegNo, dbo.tbFee.PID, dbo.tbFee.Purpose, dbo.tbFee.AmountPaid, dbo.tbFee.StudentID, dbo.tbFee.Date, dbo.tbFee.FeeID,
dbo.tbFee.SemID, dbo.tbFee.CourseID, dbo.tbFee.ModeOfPayment, dbo.tbFee.CheckNo, dbo.tbFee.DDNo, dbo.tbFee.HostelDDNo, dbo.tbFee.FRID,
dbo.tbStudent.Parentage, dbo.tbCourse.Name AS Course, ISNULL(dbo.tbSemester.SemName, ' + #st +') AS Semester
FROM dbo.tbFee INNER JOIN
dbo.tbStudent ON dbo.tbFee.StudentID = dbo.tbStudent.StudentID INNER JOIN
dbo.tbCourse ON dbo.tbFee.CourseID = dbo.tbCourse.CourseID LEFT OUTER JOIN
dbo.tbSemester ON dbo.tbFee.SemID = dbo.tbSemester.SemID Where tbFee.SemID=1
) as x
pivot (
max(AmountPaid)
for Purpose in (' + #values + ')
) as pvt
'
exec (#q)
I am getting Values of Purpose columns in #values due to the reason that number of rows can change. However instead of getting result as single row for same student having same regNo , I am getting below result :
But what I am getting is below:
In the source query for your PIVOT, you should only specify those columns which are involved in the actual pivot - namely dbo.tbStudent.Name, dbo.tbStudent.RegNo, dbo.tbFee.Purpose, dbo.tbFee.AmountPaid.
SELECT
dbo.tbStudent.Name,
dbo.tbStudent.RegNo,
dbo.tbFee.Purpose,
dbo.tbFee.AmountPaid
FROM
dbo.tbFee
INNER JOIN dbo.tbStudent ON dbo.tbFee.StudentID = dbo.tbStudent.StudentID
INNER JOIN dbo.tbCourse ON dbo.tbFee.CourseID = dbo.tbCourse.CourseID
LEFT OUTER JOIN dbo.tbSemester ON dbo.tbFee.SemID = dbo.tbSemester.SemID
Where tbFee.SemID=1
If any other columns apart from these are present, they will be factored into the pivot computation, and you will get multiple rows accordingly.

Concatenate many rows into a single text string

I'm trying to concatenate several names into a single column but I'm having trouble getting there.
DECLARE #Names VARCHAR(8000)
SELECT
p.Pato_Id
#Names = COALESCE(#Names + ', ', '') + e.First_Name + ' ' + e.Last_Name
FROM
Patos p
LEFT JOIN
Pato_Owners po
ON
po.Pato_Id = p.Pato_Id
LEFT JOIN
Person e
ON
po.Owner_Id = e.Person_Id
How can this be done?
EDIT:
When I'm making a normal select I getting
PatoID First Last
0 John Wort
0 Dan Mass
1 Till Bos
2 Wrap Sim
2 Port Lock
And what I want is:
PatoID Names
0 John Wort, Dan Mass
1 Till Bos
2 Wrap Sim, Port Lock
You have left join which indicate that you can have null names. This would reset the values of names should that occur.
;with cte as
(
SELECT
p.Pato_Id,
coalesce(e.First_Name, '') + coalesce(' ' + e.Last_Name, '') Name
FROM
Patos p
LEFT JOIN
Pato_Owners po
ON
po.Pato_Id = p.Pato_Id
LEFT JOIN
Person e
ON
po.Owner_Id = e.Person_Id
)
select t.Pato_id
,STUFF((
select ',' + [name]
from cte t1
where t1.Pato_Id = t.Pato_Id
for xml path(''), type
).value('.', 'varchar(max)'), 1, 1, '') [Names]
from cte t
group by t.Pato_id
Try this,
DECLARE #Names VARCHAR(8000)
SELECT
p.Pato_Id,
'ServerName' = COALESCE(#Names + ', ', '') + e.First_Name + ' ' + e.Last_Name
FROM
Patos p
LEFT JOIN
Pato_Owners po
ON
po.Pato_Id = p.Pato_Id
LEFT JOIN
Person e
ON
po.Owner_Id = e.Person_Id
I think you want this,
WITH Sales_CTE (Pato_Id, First, Last)
AS
(
Select p.Pato_Id , e.First , e.Last
FROM
Patos p
LEFT JOIN
Pato_Owners po
ON
po.Pato_Id = p.Pato_Id
LEFT JOIN
Person e
ON
po.Owner_Id = e.Person_Id
)
SELECT Pato_Id,
Substring((Select ',' + ISNULL(First,'') + ISNULL(Last,'') From Sales_CTE B Where B.Pato_Id=A.Pato_Id For XML Path('')),2,8000) As names
from Sales_CTE A group by Pato_Id;

UPDATE from inner complex SELECT

UPDATE DB4010.dbo.EntityStagedData
SET
EntityData = (
SELECT
geo.City + ' ' + geo.Description + ' ' + geo.Street + ' ' +
geo2.City + ' ' + geo2.Description + ' ' + geo2.Street
FROM DB4010.dbo.RouteTemplates templates
INNER JOIN DB4010.dbo.RouteTemplateClients clients
ON clients.RouteTemplateID = templates.RouteTemplateID
INNER JOIN DB4010.dbo.RouteTemplateStopMasters masters
ON masters.RouteTemplateClientID = clients.RouteTemplateClientID
INNER JOIN DB4010.dbo.RouteTemplateStopDetails details
ON details.RouteTemplateStopID = masters.PickupStopID
INNER JOIN DB4010.dbo.RouteTemplateStopDetails details2
ON details2.RouteTemplateStopID = masters.DeliveryStopID
INNER JOIN DB4010.dbo.Geofences geo
ON geo.GeofenceID = details.GeofenceID
INNER JOIN DB4010.dbo.Geofences geo2
ON geo2.GeofenceID = details2.GeofenceID
WHERE clients.RouteTemplateID = DB4010.dbo.EntityStagedData.EntityID
)
WHERE EXISTS ( SELECT RouteTemplateID FROM DB4010.dbo.RouteTemplates )
This is giving me an error:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into
column 'EntityData', table 'DB4010.dbo.EntityStagedData'; column does
not allow nulls. UPDATE fails.
I can't, for the life of me, figure out how to update+Concatenate "EntityData" from the results of the inner Select statement...
I've made a few changes:
single-letter aliases for readability
fix to proprietary SQL Server UPDATE FROM syntax
elimination of uncorrelated WHERE EXISTS clause
You may still need to decide what to do in cases where geo.City etc. contain NULL values. You may need to simply wrap the expression in COALESCE or filter NULL rows out of the join altogether.
UPDATE s SET EntityData =
geo.City + ' ' + geo.Description + ' ' + geo.Street + ' ' +
geo2.City + ' ' + geo2.Description + ' ' + geo2.Street
FROM DB4010.dbo.EntityStagedData AS s
INNER JOIN DB4010.dbo.RouteTemplateClients AS c
ON c.RouteTemplateID = s.EntityID
INNER JOIN DB4010.dbo.RouteTemplates AS t
ON t.RouteTemplateID = c.RouteTemplateID
INNER JOIN DB4010.dbo.RouteTemplateStopMasters AS m
ON m.RouteTemplateClientID = c.RouteTemplateClientID
INNER JOIN DB4010.dbo.RouteTemplateStopDetails AS d
ON d.RouteTemplateStopID = m.PickupStopID
INNER JOIN DB4010.dbo.RouteTemplateStopDetails AS d2
ON d2.RouteTemplateStopID = m.DeliveryStopID
INNER JOIN DB4010.dbo.Geofences AS geo
ON geo.GeofenceID = d.GeofenceID
INNER JOIN DB4010.dbo.Geofences AS geo2
ON geo2.GeofenceID = d2.GeofenceID;
You can wrap the first section in a COALESCE statement as such:
SET EntityData = COALESCE(( SELECT geo.City + ' ' + geo.Description
+ ' ' + geo.Street + ' ' + geo2.City + ' ' + geo2.Description + ' '
+ geo2.Street
FROM DB4010.dbo.RouteTemplates templates
INNER JOIN DB4010.dbo.RouteTemplateClients clients ON clients.RouteTemplateID =
templates.RouteTemplateID
INNER JOIN DB4010.dbo.RouteTemplateStopMasters masters ON
masters.RouteTemplateClientID = clients.RouteTemplateClientID
INNER JOIN DB4010.dbo.RouteTemplateStopDetails details ON
details.RouteTemplateStopID = masters.PickupStopID
INNER JOIN DB4010.dbo.RouteTemplateStopDetails details2 ON
details2.RouteTemplateStopID = masters.DeliveryStopID
INNER JOIN DB4010.dbo.Geofences geo ON geo.GeofenceID = details.GeofenceID
INNER JOIN DB4010.dbo.Geofences geo2 ON geo2.GeofenceID = details2.GeofenceID
WHERE clients.RouteTemplateID = DB4010.dbo.EntityStagedData.EntityID ), '')
to set the value to a blank value.
If you want to get as much information as possible, wrap each individual portion in COALESCE statements to remove NULL values, such as:
SELECT COALESCE(geo.City, '') + ' ' + COALESCE(geo.Description, '') ...
That way, if one of your values in the sub-select is NULL, you won't get a NULL value as a result of the concatenation.