I have the next two tables:
CREATE TABLE #SalesByStore (
Brand VARCHAR(10),
StoreName VARCHAR(50),
Sales DECIMAL(10,2)
)
CREATE TABLE #SalesByBrand (
Brand VARCHAR(10),
TotalSales DECIMAL(10,2)
)
I am trying to build an HTML table body using recursive string concatenation, and I need to show the sales by store ordered by brand, and after each group of stores from a same brand show the sales subtotals for that brand, like this:
I am doing it the following way:
DECLARE @tableBody NVARCHAR(MAX), @lastBrand VARCHAR(10);
SELECT @tableBody='';
SELECT
@tableBody
= @tableBody
+ CASE
WHEN @lastBrand IS NOT NULL AND @lastBrand<>SS.Brand
THEN '<tr><td colspan="2">Subtotal</td><td>'
+ (SELECT TOP 1 CAST(SB.TotalSales AS VARCHAR(15)) FROM #SalesByBrand SB WHERE SB.Brand=@lastBrand)
+ '</td></tr>'
ELSE '' END
+ '<tr><td>' + SS.Brand + '</td><td>'
+ SS.StoreName + '</td><td>' + CAST(SS.Sales AS VARCHAR(15)) + '</td></tr>',
@lastBrand = SS.Brand
FROM #SalesByStore SS
ORDER BY SS.Brand
The problem is that the sub-query that gets me the sub-total amount by brand always returns NULL because @lastBrand remains null for the sub-query (see this stack overflow question for an explain about why this happens: Why subquery inside recursive string concatenation always returns NULL?).
Can you suggest me another way to create the HTML table with subtotals in SQL Server 2005?
By the way, I need to build the HTML table in SQL Server in order to send it inside a db mail.
EDIT: I have moved the case from the ending to the beggining of the concatenation, because the subtotal row must be draw before the new brand group begins. Sorry for the mistake.
Luckily in this case, we can simply swap out your subquery for a join and select the value directly:
You've certainly come up with a clever method of creating this HTML table. Note that I've moved things around a little and hacked together a solution.
I tested with this set of data:
Alternative using GROUPING SETS and proper ordering. The strings are joined together using XML PATH.
Working SQL Fiddle
The top query in the fiddle shows the variable content after the query. The bottom query just shows you what GROUPING SETS produces.
While grouping is certainly a feature of SQL Server 2008 onwards and should replace all usage of WITH ROLLUP, this particular example can easily be switch to a WITH ROLLUP for SQL Server 2005 using 3 lines replacing the 2 shown