I don’t know if this question has been ask before. But I have a problem when concating varchars.
Let me explain:
I have this table:
CREATE TABLE Table1
(
[Field] [varchar](10) NOT NULL
)
INSERT INTO Table1
VALUES('1'),('2'),('3'),('4'),('5'),('TITLE')
And I like the output to be like this:
'[TITLE],[1],[2],[3],[4],[5]'
I want the ‘TITLE’ to be order first then 1,2,3,4,5
So this query will return the ordered result. I do not have more numbers then the length of the ‘TITLE’
SELECT
*
FROM
Table1
ORDER BY
LEN([Field]) DESC,
[Field] ASC
Then i usually concat the varchar like this:
DECLARE @cols VARCHAR(MAX)
SELECT @cols = COALESCE(@cols + ','+QUOTENAME([Field]),
QUOTENAME([Field]))
FROM
Table1
ORDER BY
LEN([Field]) DESC,
[Field] ASC
But this return:
'[5]'
Which I find is really strange. Can someone please explain why?
I know that there is a alternative solution to concating a varchar. Like this:
DECLARE @cols VARCHAR(MAX)
SELECT @cols=STUFF
(
(
SELECT
',' +QUOTENAME([Field])
FROM
Table1
ORDER BY
LEN([Field]) DESC,
[Field] ASC
FOR XML PATH('')
)
,1,1,'')
This will return my expected result like this:
'[TITLE],[1],[2],[3],[4],[5]'
EDIT
Suggestion that @cols is null at the begining cant be it. Becuase if i remove the order by. Like this:
DECLARE @cols VARCHAR(MAX)
SELECT @cols = COALESCE(@cols + ','+QUOTENAME([Field]),
QUOTENAME([Field]))
FROM
Table1
My result will be like this:
'[1],[2],[3],[4],[5],[TITLE]'
EDIT1
This will not work:
DECLARE @cols VARCHAR(MAX)
SELECT @cols = COALESCE(@cols + ','+QUOTENAME([Field]),
QUOTENAME([Field]))
FROM(
SELECT [Field]
FROM
Table1
ORDER BY
LEN([Field]) DESC,
[Field] ASC
) AS t
Because it will give a exception message like this:
Msg 1033, Level 15, State 1, Line 17 The ORDER BY clause is invalid in
views, inline functions, derived tables, subqueries, and common table
expressions, unless TOP or FOR XML is also specified.
EDIT2
Like I expected. I cannot do this:
SELECT @cols, @cols = COALESCE(@cols + ','+QUOTENAME([Field]),
QUOTENAME([Field]))
FROM
Table1
ORDER BY
LEN([Field]) DESC,
[Field] ASC
Becuase this will raise an exception like this:
Msg 141, Level 15, State 1, Line 9 A SELECT statement that assigns a
value to a variable must not be combined with data-retrieval
operations.
You can have a look at this article PRB: Execution Plan and Results of Aggregate Concatenation Queries Depend Upon Expression Location
You get a different execution plan when you use expressions in the order by clause.
The sort is applied after Compute Scalar instead of before.
The safe way to concatenate strings with an order by is to use
for xml.