The code works fine except for
SELECT DISTINCT isnull(#FEATURE + ', ', ',') + Feature
FROM [128.100.194.219, 1435].[EMSData].[dbo].[vOSLRoomFeatures] as rf2 where (rf2.roomid = rf.roomid)
for xml path('')),
which is giving me problems. I do not know how to get rid of the first comma. I have tried substring but it removes all the commas(I guess since it's in a select statement). I even tried
COALESCE(#FEATURE + ', ', '') + FEATURE but I end up with the same result, either no commas or one extra comma at the end or at the very beginning.
DECLARE #FEATURE VARCHAR(500)
-- INSERT INTO BookableRooms IF NOT EXISTS ROOM NUMBER
INSERT INTO dbo.BookableRooms_test (FK_Building_code,
Room_num,Other_room_name,
Capacity_from,
Capacity_to,
Accessiblity,AV_book_separate,Flooring_type,Features,
Food_drink_allowed, Alcohol_allowed,Internet,
[Owner],FK_BookingContact_ID,
LCD_projector,Computer,FK_SpaceManager_code,Last_updated_date,Last_updated_by,SpecialFlag)
SELECT DISTINCT CASE
WHEN rf.[Building Reference] is null or rf.[Building Reference] = '' THEN 'HH'
ELSE rf.[Building Reference]
END,
[ROOMID],[Description],
(SELECT MIN(rf2.CAPACITY) FROM [128.100.194.219, 1435].[EMSData].[dbo].[vOSLRoomFeatures] AS rf2 WHERE rf2.ROOMID = rf.ROOMID),
(SELECT MAX(rf2.CAPACITY) FROM [128.100.194.219, 1435].[EMSData].[dbo].[vOSLRoomFeatures] AS rf2 WHERE rf2.ROOMID = rf.ROOMID),
dbo.iszero([Wheelchair Accessible]), dbo.iszero(rf.[Separate AV]),dbo.isflat(rf.[Flat Floor]),
(
SELECT DISTINCT isnull(#FEATURE + ', ', ',') + Feature
FROM [128.100.194.219, 1435].[EMSData].[dbo].[vOSLRoomFeatures] as rf2 where (rf2.roomid = rf.roomid)
for xml path('')),
dbo.iszero(rf.[Food and Drink]),dbo.iszero(rf.[Alcohol]),dbo.iszero(rf.[Room Internet]),
'HH',5,
dbo.iszero(rf.[Digital Projector]),dbo.iszero(rf.[Computer]),'HH',GetDate(),'System',dbo.iszero(rf.[Restricted])
FROM [128.100.194.219, 1435].[EMSData].[dbo].[vOSLRoomFeatures] as rf where NOT EXISTS(
SELECT 1 FROM dbo.BookableRooms_test b WHERE
b.Room_num = rf.ROOMID);
Use Stuff but on the outer side of subquery:
stuff ((SELECT DISTINCT ',' + Feature
FROM [128.100.194.219, 1435].[EMSData].[dbo].[vOSLRoomFeatures] as rf2
WHERE (rf2.roomid = rf.roomid)
for xml path('')), 1, 1, '')
Use the STUFF function to remove the leading comma.
SELECT DISTINCT STUFF(',' + Feature
FROM [128.100.194.219, 1435].[EMSData].[dbo].[vOSLRoomFeatures] as rf2 where (rf2.roomid = rf.roomid)
for xml path('')),1,1,''),
I am not sure what you are trying to achieve. If my guess was wrong, it would good if you told us what results you expect in which situation.
Try this
CASE WHEN #FEATURE IS NULL THEN NULL ELSE #FEATURE + ', ' END
Related
I have applied XML PATH and Stuff to show multiple records in single cell, which is all working fine but I am required to show each record in cell in separate single line i.e char(13) but in my solution I am getting result like
#x0D;; Canvey
; government
; More information needed
; More information required
Script
SELECT
ans.Id
,ans.ResponseId
,STUFF((SELECT DISTINCT
char(13)+char(10) +
'; ' + cod.Name
,' ' + COUNT(cod.Name)
FROM [dbo].[Highlights] as h
INNER JOIN [dbo].[CodedHighlights] as ch on h.Id = ch.HighlightId
INNER JOIN [dbo].[Codes] as cod on ch.CodeId = cod.Id
WHERE h.AnswerId = ans.Id
GROUP BY cod.Name
FOR XML PATH('')), 1, 1, '' ) [ANSWER/CODES]
FROM [dbo].[Answers] as ans
Try this
DECLARE #result VARCHAR(100)=
STUFF(
(
SELECT TOP 5 CHAR(13) + [name]
FROM sys.objects
FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,1,'');
PRINT #result;
You must use TYPE to get a natively typed XML in order to use the .value() method. This will implicitly re-escape all entities to their actual string values.
Furthermore, I use PRINT, as the typical grid result would not show the line breaks.
Hint: If you use CHAR(13)+CHAR(10) you'd have to add ,1,2,'') as STUFF()'s paramaters.
I have a temp table called #temp, and I need to get all the CDate column from that table, to build a string.
The CDate list in that table is (20171209, 20171210....20171223)
I expected to see
'A.[20171209] as [20171209], A.[20171210] as [20171210],
A.[20171211] as [20171211], A.[20171212] as [20171212],
A.[20171213] as [20171213], A.[20171214] as [20171214],
A.[20171215] as [20171215], A.[20171216] as [20171216],
A.[20171217] as [20171217], A.[20171218] as [20171218],
A.[20171219] as [20171219], A.[20171220] as [20171220],
A.[20171221] as [20171221], A.[20171222] as [20171222],
A.[20171223] as [20171223], '
however the result I got is missing the first date , ie 'A.[20171209] as [20171209]'
Here is my code:
SELECT
#col2 = ISNULL(#col2 + 'A.' + QUOTENAME(CDate) + ' as ' + QUOTENAME(CDate) + ', ' , '')
FROM
(SELECT DISTINCT CDate FROM #temp) AS tmp;
Your current approach will not work in some cases, it is an undocumented feature, always use For Xml path to concatenating the rows into csv.
SET #col2 = stuff((SELECT ', A.' + Quotename(CDate) + ' as '
+ Quotename(CDate)
FROM (SELECT DISTINCT CDate
FROM #temp) a
FOR xml path('')),1,1,'')
SELECT REPLACE('10,6 7 7,900 11,027,900', ' ', '')
SELECT REPLACE('10,2 27,900 10,6 7 7,900 11,027,900', ' ', '')
Bad Result:
10,677,90011,027,900
10,227,90010,677,90011,027,900
Good Result:
10,677,900 11,027,900
10,227,900 10,677,900 11,027,900
This is an odd requirement. Before this goes downhill, I suggest you normalize your table properly. Anyway, if you're stuck with what you have for now, here is a way to solve your problem.
First, you need a string splitter, to split strings by comma. I use DelimitedSplit8K, written by Jeff Moden and improved by the members of SQL Server Central community.
After splitting the string, check if the value of each item after the space is removed has a length of 3. If yes, concatenate the new string (space removed). Else, concatenate the original item.
WITH Tbl(OriginalString) AS(
SELECT '10,6 7 7,900 11,027,900' UNION ALL
SELECT '10,2 27,900 10,6 7 7,900 11,027,900'
),
TblSplitted(originalString, ItemNumber, Item) AS (
SELECT *
FROM Tbl t
CROSS APPLY dbo.DelimitedSplit8K(t.OriginalString, ',')
)
SELECT *
FROM Tbl t
CROSS APPLY(
SELECT STUFF((
SELECT ',' +
CASE
WHEN LEN(REPLACE(s.Item, ' ', '')) = 3 THEN REPLACE(s.Item, ' ', '')
ELSE s.Item
END
FROM TblSplitted s
WHERE s.originalString = t.OriginalString
ORDER BY s.ItemNumber
FOR XML PATH('')
), 1, 1, '')
) x(NewString);
I am attempting the following query in SQL Server:
SELECT AlertID,
(STUFF((SELECT ', ' + t2.LocationDesc
FROM app_Location t2
WHERE t1.LocationCode = t2.LocationCode
FOR XML PATH (''))
, 1, 1, '')) as Location,
CensusTime,
InsertDate
FROM MultiCensusEmail
INNER JOIN app_Location t1 ON MultiCensusEmail.Location = t1.LocationCode
I want it to return a comma delimited list for the locations, but they are showing up on separate rows.
I want the row to end up something like this:
5A8056A7-5D8F-4678-B980-9E54987EE70C | AS EMERGENCY DEPT, BN CARDIAC,
BN CHEST PAIN UNIT | 7:00 | 2016-10-17 9:17:55.067
You don't provide much detail about your data, but I think that your JOIN is not needed.
SELECT AlertID,
(STUFF((SELECT ', ' + t2.LocationDesc
FROM app_Location t2
WHERE MultiCensusEmail.Location = t2.LocationCode // probably you want another condition here
FOR XML PATH (''))
, 1, 1, '')) as Location,
CensusTime,
InsertDate
FROM MultiCensusEmail
What do you want to "group by" (e.g. what data item does have multiple locations)?
The "outer" query should produce the wanted rows without "location" (in your case), and the "inner" FOR XML query should have a condition that filters the "locations" you want to have comma-separated.
I was able to accomplish what I wanted to do using COALESCE:
declare #Location varchar(max)
select #Location = COALESCE(#Location + ', ', '') + LocationDesc
From app_Location INNER JOIN MultiCensusEmail ON MultiCensusEmail.Location = app_Location.LocationCode
where upper(UserID) = 'test'
select distinct AlertID, #Location, CensusTime, InsertDate
from MultiCensusEmail
where upper(UserID) = 'test'
Here the code from my function:
-- Get Country Names
DECLARE getCountriesName CURSOR FOR
SELECT c.Name
FROM VocabCountry c
RIGHT OUTER JOIN ProjectCountryRelations cr
ON cr.CountryId = c.Id
WHERE
c.Id = #project_id;
-- Finally Create list to return
OPEN getCountriesName;
FETCH NEXT FROM getCountriesName INTO #Name;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #listOfItems = #listOfItems + #Name + ', '
FETCH NEXT FROM getCountriesName INTO #Name;
END;
CLOSE getCountriesName;
DEALLOCATE getCountriesName;
I am expecting a list of comma separated values, for example, like so:
Canada, United States of America,
I verified that the SELECT returns the countries expected.
Thanks for any help!
Eric
If you're on SQL Server 2008 or newer, you could easily do this with a single SELECT and some FOR XML PATH magic :-)
SELECT
STUFF(
(SELECT ',' + c.Name
FROM VocabCountry c
RIGHT OUTER JOIN ProjectCountryRelations cr
ON cr.CountryId = c.Id
FOR XML PATH('')
), 1, 1, '')
That should return a comma-separated list of those country names for you. No ugly and awful cursor needed!
Using the FOR XML PATH will concat the values with commas.
Using the STUFF Function will remove the first comma you don't want.
So use this:
SELECT
STUFF(
(SELECT ',' + c.Name
FROM VocabCountry c
RIGHT OUTER JOIN ProjectCountryRelations cr
ON cr.CountryId = c.Id
WHERE cr.Id = #project_id
FOR XML PATH('')
), 1, 1, '');
See this fiddle: http://sqlfiddle.com/#!3/fd648/21