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

user1554650
  • 47
  • 10
  • 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. http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/ – Sean Lange Oct 05 '16 at 14:26
  • @Sean Lange I have modified the question – user1554650 Oct 05 '16 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. – Sean Lange Oct 05 '16 at 18:03

1 Answers1

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];
Solomon Rutzky
  • 46,688
  • 9
  • 128
  • 171
  • 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 Oct 06 '16 at 05:14
  • @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. – Solomon Rutzky Oct 08 '16 at 14:39
  • Thanks, for clarification! – gofr1 Oct 08 '16 at 15:31
  • @gofr1 No problem. I just updated my answer to include some example code to illustrate the behavior. Enjoy :) – Solomon Rutzky Oct 11 '16 at 06:29
  • @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”](http://stackoverflow.com/questions/31274521/converting-accented-characters-in-varchar-to-xml-causing-illegal-xml-characte/39922862#39922862) ? – Solomon Rutzky Oct 11 '16 at 17:33