0

I have a parameter in stored procedure named grouplist. This contain column names in comma seperated values.

for eg: @grouplist='Class1,Class2,Class3'

My query is

Set @Sql= 'select ' + @grouplist +' from #final

My result is

Table result

These columns contains value "ZZTotal" value. Its should be replaced with "Total" .These are dynamic columns.

I need to replace zztotal with total.

In the final output it should be like this

final output

Any help appreciated

3
  • 4
    Your question lacks any context to make it understandable. I can't tell from reading this what you are trying to do or what the problem is. You might start here. spaghettidba.com/2015/04/24/… Commented Oct 5, 2016 at 14:26
  • @Sean Lange I have modified the question Commented Oct 5, 2016 at 17:56
  • Well the question is certainly different, sadly it isn't any more clear than it was before. I would be leery of a query with columns dynamically being selected like this. If you are stuck using dynamic sql you are going to have to jump through some serious hurdles to pull this off. You need to provide a LOT more information here. You will likely need a string splitter to rebuild your dynamic sql. Commented Oct 5, 2016 at 18:03

1 Answer 1

2

There is a larger problem that is being ignored: there is most likely a reason that the text is already ZZTotal instead of Total. And that reason is most likely in order to maintain proper row ordering (i.e. keeping the totals at the bottom).

The ZZTotal rows are most likely being generated automatically by SQL Server via the ROLLUP option of the GROUP BY clause. Initially, the ROLLUP option places NULL in each "group" that is being rolled-up since the string "Total" (or any string) won't fit into a column of non-string datatypes. I am guessing that the NULL values were replaced with ZZTotal via ISNULL() when dumping the results into #final.

The current problem is that if you replace the ZZTotal values with Total, then the "Total" rows will possibly not be at the bottom of that grouping, at least not for any groupings that contain strings starting with U..., or Tp..., or Tou..., and so on.

  1. The first step is to add an IDENTITY column to the #final table. You do this by changing the query that creates and populates #final by adding IDENTITY(INT, 1, 1) AS [RowNum], as the first column of the SELECT statement.

  2. The second step is to change the ISNULL(column, 'ZZTotal') of the query that populates #final to instead be (for Class2, for example):

    IIF(GROUPING(class2) = 0, class2, N'Total for ' + class1) AS [Class2]
    

    Please note the use of "class1", not "class2", at the end of N'Total for ' + class1.

  3. The third / final step is to add ORDER BY [RowNum] to the end of the Set @Sql= statement. The final query should be something like:

    SELECT Class1, Class2, Class3 FROM #final ORDER BY [RowNum];
    

Example 1: ROLLUP default behavior

SELECT ss.[name] AS [SchemaName],
       so.[type_desc] AS [ObjectType],
       COUNT(*) AS [ObjectCount]
FROM [master].sys.schemas ss
INNER JOIN [master].sys.objects so
        ON so.[schema_id] = ss.[schema_id]
GROUP BY ss.[name], so.[type_desc] WITH ROLLUP;

Example 2: ROLLUP with NULLs replaced in GROUPING rows

SELECT IIF(GROUPING(ss.[name]) = 0, ss.[name], N'Total') AS [SchemaName],
       IIF(GROUPING(so.[type_desc]) = 0,
           so.[type_desc], 
           IIF(GROUPING(ss.[name]) = 0,
               N'Total for ' COLLATE Latin1_General_CI_AS_KS_WS + ss.[name],
               N'---------------------------------------->')
          ) AS [ObjectType],
       COUNT(*) AS [ObjectCount]
FROM [master].sys.schemas ss
INNER JOIN [master].sys.objects so
        ON so.[schema_id] = ss.[schema_id]
GROUP BY ss.[name], so.[type_desc] WITH ROLLUP;

Example 3: Adding IDENTITY column and INTO clause to Example #2

SELECT IIF(GROUPING(ss.[name]) = 0, ss.[name], N'Total') AS [SchemaName],
       IIF(GROUPING(so.[type_desc]) = 0,
           so.[type_desc], 
           IIF(GROUPING(ss.[name]) = 0,
               N'Total for ' COLLATE Latin1_General_CI_AS_KS_WS + ss.[name],
               N'---------------------------------------->')
          ) AS [ObjectType],
       COUNT(*) AS [ObjectCount],
       IDENTITY(INT, 1, 1) AS [RowNum]
INTO #TempResults
FROM [master].sys.schemas ss
INNER JOIN [master].sys.objects so
        ON so.[schema_id] = ss.[schema_id]
GROUP BY ss.[name], so.[type_desc] WITH ROLLUP;

SELECT * FROM #TempResults ORDER BY [RowNum];
Sign up to request clarification or add additional context in comments.

4 Comments

Nice one! That much more informative answer than mine (deleted). One stupid question, I haven't used group by with rollup, it always add ZZ to total automatically or this is something that you add manually?
@gofr1 No, ROLLUP has to use NULL, probably because it is the only common "value" that can be used across all datatypes. The "Total" and "ZZTotal" are manually added after the fact via ISNULL or IIF / CASE as I described here.
@gofr1 No problem. I just updated my answer to include some example code to illustrate the behavior. Enjoy :)
@gofr1 True, and I appreciate the sentiment. Perhaps you would find the following answer interesting and of merit? ;) Converting accented characters in varchar() to XML causing “illegal XML character” ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.