The only thing you have missed in your query is the
GROUP BY
clause, but using FOR XML PATH you are going to have to use correlated sub-queries I think. i.e.
SELECT
t1.[no]
,STUFF((SELECT ', ' + cast(t2.code as varchar)
FROM test t2
WHERE t1.[no]=t2.[no] ORDER BY t2.code
FOR XML PATH(''), TYPE).value('text()[1]','nvarchar(max)'),1,1, N'') AS codes
,STUFF((SELECT ', ' + cast(t2.qty as varchar)
FROM test t2
WHERE t1.[no]=t2.[no] ORDER BY t2.code
FOR XML PATH(''), TYPE).value('text()[1]','nvarchar(max)'),1,1, N'') AS qtys
FROM test t1
GROUP BY t1.[no]
Which gives the results
No Codes Qtys
1055 956, 957, 958, 959, 960 10, 9, 5, 4, 3
1056 958, 959 5, 4
[NOTE - I just created a table test that had your data from the question in it - replace "test" with your table join]
If you absolutely cannot use sub-queries then you can use COALESCE but the only way I could get
that to work was with a loop (yuk!) like this
DECLARE @start int = (SELECT CAST(MIN([No]) AS Int) FROM test)
DECLARE @end int = (SELECT CAST(MAX([No]) AS Int) FROM test)
DECLARE @results table ([no] varchar(4), codes varchar(max), qtys varchar(max))
WHILE @start <= @end
BEGIN
DECLARE @listCode VARCHAR(MAX) = null
DECLARE @listQty VARCHAR(MAX) = null
SELECT @listCode = COALESCE(@listCode+',' ,'') + CAST(code AS Varchar),
@listQty = COALESCE(@listQty+',' ,'') + CAST(qty AS Varchar)
FROM test
WHERE [no] = CAST(@start AS Varchar)
IF @listCode IS NOT NULL
BEGIN
INSERT INTO @results ([no], codes, qtys) VALUES (cast(@start as varchar), @listCode, @listQty)
END
SET @start += 1
END
SELECT * FROM @Results