Invalid object name in a XML Path / Stuff combination - sql-server

I am trying to get some values from different rows into a single column, and I keep getting this error :
Invalid object name 't'
The query is rather big and complicated so I narrowed it down to a simple part that still gives me the error.
select
IDs = stuff( ( select ',' + convert(varchar, t2.ChassisID)
from t as t2
where t2.ChassisID = 42 --t.ChassisID
for XML path('')
)
, 1, 1, ''
)
from ( select ch.ChassisID, p.GPS
from tblChassis ch
inner join tblPlace p on ch.BestemmingID = p.PlaceID
) t
group by t.Gps
I tried changing the where clause to a fixed number (42) instead of t.ChassidID and still get the error, so there is only one place left that could cause the error I assume, but I cant see why.
I probably am missing something simple but I just cannot see it.
What is wrong with this query ?
I am using Sql Server 2014

Try declaring your filtered table in a CTE, then referencing this CTE both times.
;WITH FilteredChassis AS
(
select
ch.ChassisID,
p.GPS
from
tblChassis ch
inner join tblPlace p on ch.BestemmingID = p.PlaceID
)
select
t.Gps,
IDs = stuff( ( select ',' + convert(varchar, t2.ChassisID)
from FilteredChassis as t2
where t2.Gps = t.Gps
for XML path('')
)
, 1, 1, ''
)
from
FilteredChassis AS t
group by
t.Gps
I've made the link through gps, I believe that's what you need.

Related

Is there a way in the STUFF(... FOR XML) function in SQL to prevent duplicate values?

To keep this short, here's my SQL code:
SELECT
EmailAddress,
FormsSubmitted = STUFF(
(
SELECT ',' + SourceSubType
FROM UK_AGT_AgentForms_TEST_DE a
WHERE a.EmailAddress = b.EmailAddress
FOR XML PATH('')
), 1, 1, ''),
DEDate
FROM UK_AGT_AgentForms_TEST_DE b
GROUP BY b.EmailAddress, b.DEDate
And, here's the result set it produces:
Is there a way to prevent duplicate values from showing up in the FormsSubmitted column from within the query above? Or do I need to do some "post processing" to remove the duplicates?
Add a DISTINCT to the inner SELECT query.

csv from subquery in IN() causes conversion error

CROSS APPLY (
SELECT
ISNULL(
(
SELECT
SUM (R.CALORIE)
FROM
TA_RECIPE AS R
WHERE
R.NO_RECIPE IN ([mp].recipe_ids)
OR R.NO_RECIPE IN ([tags2].recipe_ids)
),
0
) AS caloriePerPortion
) AS [CAL]
The problem is in the part
R.NO_RECIPE IN ([mp].recipe_ids)
OR R.NO_RECIPE IN ([tags2].recipe_ids)
The recipe_ids contain comma seperated lists
when there's only one id in the recipe_ids it works fine but if there is actually a list in recipe_ids sql server interprets this as a varchar instead of a list of integers
wrapping them in STRING_SPLIT causes the query to become very slow (adds seconds to the execution time)
wrapping them in STRING_SPLIT causes the query to become very slow
But that's the only way it can work.
select *
from t
where c in ('1,2,3,4,5')
just doesn't do what you want.
the data isn't stored as csv but was retrieved like that throug cross apply with for xml path
I changed it to
SELECT DISTINCT
MM.MAP_ID AS mapId,
MM.MENU_ID AS menuId,
stuff((select ',' + CAST(RECIPES.recipe_ids AS VARCHAR(MAX)) for xml path('')), 1, 1, '') AS planningRecipe_ids
FROM MM
LEFT JOIN MP ON MM.MENU_ID = MP.MENU_ID
LEFT JOIN RECIPES ON RECIPES.PLANNING_MENU_ID = MP.PLANNING_MENU_ID
but then the for xml path doesn't work

How to add a variable in the open query in a stored procedure

I have an stored procedure that receives a parameter of store id. I need that variable to be added in a openquery tsql script I am not able to do it.. Look in my code where it says #var thats where the variable will need to work
I tried to reference to this https://support.microsoft.com/en-us/help/314520/how-to-pass-a-variable-to-a-linked-server-query but I cant get it to work
SELECT x.*
FROM (
SELECT tl.title_log_sts_cd
,tl.ro_vin
,tl.ro_store_id
,ll.CurrentLoanStatus
,bc.vin
,bc.BorrowerId
,ll.DisplayLoanNumber
,CONVERT(DATE, CONVERT(VARCHAR(10), ll.CreateDateKey, 7)) LoanDate
,CONCAT (
bb.LastName
,','
,bb.FirstName
) CustomerName
,ll.CurrentPrincipalBalanceAmt + ll.CurrentFeeBalanceAmt TotalDue
FROM OPENQUERY(TLXPRD, 'SELECT * FROM TITLE_LOG
WHERE title_log_sts_cd in (''Ready to Send to DMV'', ''Sent to DMV'')
and ro_store_id =#VAR ') AS tl
JOIN EIS.Borrower.Collateral bc WITH (NOLOCK) ON tl.ro_vin = bc.Vin
LEFT JOIN eis.loan.loan ll WITH (NOLOCK) ON ll.BorrowerId = bc.BorrowerId
AND convert(DATE, tl.created_ts) = CONVERT(DATE, CONVERT(VARCHAR(10), ll.CreateDateKey, 7))
LEFT JOIN EIS.Borrower.Borrower BB ON bb.borrowerid = ll.BorrowerId
) AS x
ORDER BY vin
Expected get some data from oracle join it in with tsql
I didn't totally get what you are trying to do but I hope this is what you are looking for.
FROM OPENQUERY(TLXPRD, concat( 'SELECT * FROM TITLE_LOG
WHERE title_log_sts_cd in (''Ready to Send to DMV'', ''Sent to DMV'')
and ro_store_id =', cast(#VAR as nvarchar(50) ) ))
basically, you had your variable in your string but you want to have it as a value.
so we get the value and put it in your string.

Surrounding query with parenthesis cause error For XML

When trying to wrap query for further processing I get an error by just putting parenthesis around the query. See query below, if I simply remove the wrapping parenthesis, the query works. But when I use the parenthesis I get this error:
Incorrect syntax near the keyword 'for'
(
select '; ' + [NAME]
from (select a.[NAME] as 'NAME'
from [MS].[dbo].[A_POSITIONS] a
where a.ID = 208418
except
select top 1 b.[NAME]
from [MS].[dbo].[A_POSITIONS] b
where b.ID = 208418) as c
for XML PATH(''),TYPE
)
Anyone have an idea on why this is happening?
Thanks!
Adding the parenthesis alone around your query leads to an error, but if you type a SELECT before the opening parenthesis the code will run, meaning that you can use it for further processing:
if OBJECT_ID('A_POSITIONS') is not null
drop table [dbo].[A_POSITIONS]
create table [dbo].[A_POSITIONS]([ID] int,[Name] varchar(100))
insert into [dbo].[A_POSITIONS] values
(208418, 'one'),(208418, 'two'),(208418, 'three'),(208418, 'four'),(208418, 'five')
select
(
select '; ' + [NAME]
from (select a.[NAME] as 'NAME'
from [MS].[dbo].[A_POSITIONS] a
where a.ID = 208418
except
select top 1 b.[NAME]
from [MS].[dbo].[A_POSITIONS] b
where b.ID = 208418) as c
for XML PATH(''),TYPE
)
One last consideration: TOP keyword without an ORDER BY clause is non-deterministic.
From Microsoft Docs (more info here):
When TOP is used in conjunction with the ORDER BY clause, the result set is limited to the first N number of ordered rows; otherwise, it returns the first N number of rows in an undefined order
So you should really consider adding an ORDER BY to the second part of your query:
select '; ' + [NAME]
from (select a.[NAME] as 'NAME'
from [MS].[dbo].[A_POSITIONS] a
where a.ID = 208418
except
select top 1 b.[NAME]
from [MS].[dbo].[A_POSITIONS] b
where b.ID = 208418
--Add an ORDER BY clause here
) as c
for XML PATH(''),TYPE

SQL: How to CONCAT value

How can I return the values of MainEmail in the query below, delimited by commas and still count MDCselect?
declare #MainHospital varchar(50)='hospital 1'
select distinct mainhospital , f.Item, count(*) Count
from SurveyPicList s
cross apply splitstrings(s.MDCselect,':') as f
WHERE MainHospital = #MainHospital
GROUP BY MainHospital, f.Item
ORDER BY Count DESC
To be clear the above returns this: http://i.imgur.com/F1oPU6P.jpg
So there were 3 separate entries/people that selected "02-Eye". I want to list out their emails(MainEmail) comma delimited. Please let me know if I am unclear.
Assuming from your use of CROSS APPLY that you are using SQL Server, and that it is at least version 2005, you can use XML to do the concatenation as follows:
declare #MainHospital varchar(50)='hospital 1';
select mainhospital , f.Item, count(*) Count
,Stuff(
(select distinct ', ' + m.MainEmail
from SurveyPicList m
where m.MainHospital = #MainHospital
and ':' + m.MDCselect + ':' like '%:' + f.Item + ':%'
FOR XML PATH ('')),
1, 2, '') as Emails
from SurveyPicList s
cross apply splitstrings(s.MDCselect,':') as f
WHERE MainHospital = #MainHospital
GROUP BY MainHospital, f.Item
ORDER BY Count DESC
From the name I am assuming that splitstrings splits its first argument into items separated by its second argument. Hence I used like to check for f.Item in m.MDCselect in the WHERE condition of the subselect. Actually, what this WHERE condition is doing is collecting all the rows from another instance of the same table that match one record in the final grouped output.

Resources