Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSRS automatically aliasing a subquery column using FOR XML

I have a query running against a SQL Server database. One of the columns in it uses the STUFF() function.

When I run the query in a SQL editor window, the resulting value looks like this:

1234

When I try to use this query in an SSRS report, SSRS automatically puts a column alias within the STUFF() function, resulting in a value that looks like this:

<Expr1>, 1</Expr1><Expr1>, 2</Expr1><Expr1>, 3</Expr1><Expr1>, 4</Expr1>

The only difference between the two is that when I save the query in SSRS, the term "AS Expr1" is added automatically (see code below).

How can I prevent SSRS from adding this alias automatically and run the query as it is?

   SELECT 
        FirstName, 
        LastName, 
        CourseTitle,
        LastLoginDate,
        NoOfModules,
        COUNT(CourseCompleted) AS ModulesStarted,
        STUFF(
          (
            SELECT ','  + CAST(CourseModule AS varchar(20)) -- SSRS puts "AS Expr1" here
            FROM EDSF 
            WHERE 
                FirstName = e.FirstName AND 
                LastName = e.LastName AND 
                Coursecompleted = '1' AND 
                CourseTitle = e.CourseTitle
            FOR XML PATH('')
          ),1,1,''
         ) AS CoursesCompleted
    FROM EDSF  e
    WHERE 
        Coursecompleted = '1' OR 
        Coursecompleted = '0'
    GROUP BY 
        FirstName, 
        LastName, 
        CourseTitle,
        LastLoginDate,
        NoOfModules;

EDIT: the code has been rearranged and the question reworded to make the issue clearer. I'm NOT having a problem aliasing the returned column itself: instead, SSRS is actually adding an alias to the subquery within my STUFF() function, resulting in extra junk within the field itself.

like image 864
muyi ani Avatar asked Oct 28 '14 17:10

muyi ani


People also ask

How do I create a column alias?

To create column aliases: Type: SELECT column1 [AS] alias1, column2 [AS] alias2, ... columnN [AS] aliasN FROM table; column1, column2, ..., columnN are column names; alias1, alias2, ..., aliasN are their corresponding column aliases; and table is the name of the table that contains column1, column2, ....

What does FOR XML PATH do?

We can use FOR XML PATH to prepare a comma-separated string from the existing data. Let's create an Authors table and insert a few records into it. In the data, we can see we have an ID column and the AuthorName column. If we just select the records, it gives the output in the following format.

How does FOR XML PATH work in SQL?

A SELECT query returns results as a rowset. You can optionally retrieve formal results of a SQL query as XML by specifying the FOR XML clause in the query. The FOR XML clause can be used in top-level queries and in subqueries. The top-level FOR XML clause can be used only in the SELECT statement.

How do you introduce an existing subquery?

A subquery that is introduced with exists is different from other subqueries, in these ways: The keyword exists is not preceded by a column name, constant, or other expression. The subquery exists evaluates to TRUE or FALSE rather than returning any data.


1 Answers

I think there's some confusion in the comments originally: the question isn't about giving a column an alias, the question is why SSRS won't allow the subquery within the STUFF() command to exist without an alias. XML is interpreting that and including the column name in the field values itself, converting the input of "1", "2", "3", and "4" to (formatting as code because it's being interpreted as HTML):

"<Expr1>, 1</Expr1><Expr1>, 2</Expr1><Expr1>, 3</Expr1><Expr1>, 4</Expr1>" 

I'm pretty sure there's a way to tell FOR XML to ignore the column names, and I'm also pretty sure that the stored procedure option is a better way to go. That said, though, there are times a stored procedure isn't an option, and so I'll include a way of getting rid of the offending values with REPLACE()

SELECT 
    FirstName,
    LastName,
    CourseTitle,
    lastlogindate,
    Noofmodules, 
    COUNT(Coursecompleted) AS modulesstarted,
    REPLACE(REPLACE(REPLACE('<' + 
      STUFF((
        SELECT ','  + CAST(CourseModule AS varchar(20)) AS Expr1
        FROM Esdf 
        WHERE 
            FirstName = e.FirstName
            AND LastName = e.LastName
            AND Coursecompleted = '1'
            AND CourseTitle = e.CourseTitle
        FOR XML PATH('')),1,1,''
      ), '<Expr1>', ''), '</Expr1>', '') , ',', ''
     ) AS CoursesCompleted
FROM Esdf  e
WHERE 
    Coursecompleted = '1' OR
    Coursecompleted = '0'
GROUP BY 
    FirstName, 
    LastName, 
    CourseTitle,
    lastlogindate, 
    Noofmodules
like image 103
AHiggins Avatar answered Jan 02 '23 16:01

AHiggins