Home All Groups Group Topic Archive Search About

Help! CUBE? ROLLUP? or COMPUTE BY?

Author
13 Aug 2005 12:10 PM
OKLover
Help! CUBE? ROLLUP? or COMPUTE BY?


Giving a table's content as below...

Date        Area    Product        Amount
------------------------------------------------------------------------------
2005/07/23    CA    Book        150
2005/07/29    NY    Pen        70
2005/08/03    CA    Pen        500
2005/08/04    CA    Book        200
2005/08/05    NY    Book        270


May i ask how to get the result as below?

Area    Book            Book            Pen            Pen ------------------------------------------------------------------------------------- CA    SUM(Book_CA_thisMonth)    SUM(Book_CA_thisyear)    SUM(Pen_CA_thisMonth)    SUM(Pen_CA_thisyear) NY    SUM(Book_NY_thisMonth)    SUM(Book_NY_thisyear)    SUM(Pen_NY_thisMonth)    SUM(Pen_NY_thisyear)

Should i use CUBE? ROLLUP? or COMPUTE BY? What's the correct SELECT syntax?

Author
13 Aug 2005 8:04 PM
John Bell
Hi

COMPUTE/COMPUTE BY are available for backward compatibility and there should
not be used in new code. The information obtained by using ROLLUP would be:

CREATE TABLE myData([Date] datetime,Area char(2),Product char(4),Amount int)

INSERT INTO myData([Date],Area,Product,Amount)
SELECT '20050723','CA','Book', 150
UNION ALL SELECT '20050729','NY','Pen', 70
UNION ALL SELECT '20050803','CA','Pen', 500
UNION ALL SELECT '20050804','CA','Book', 200
UNION ALL SELECT '20050805','NY','Book', 270

CREATE VIEW MyMonthlyValues AS
SELECT YEAR([Date]) AS Year,  MONTH([Date]) AS [Month], Area, Product, Amount
FROM MyData

SELECT CASE WHEN (GROUPING([Year]) = 1) THEN 'All' ELSE CAST([Year] AS
CHAR(5)) END AS [Year],
CASE WHEN (GROUPING([Month]) = 1) THEN 'All' ELSE CAST([Month] AS CHAR(4))
END AS [Month],
CASE WHEN (GROUPING([Area]) = 1) THEN 'All' ELSE [Area]  END AS [Area],
CASE WHEN (GROUPING([Product]) = 1) THEN 'All' ELSE [Product] END AS
[Product],
SUM(Amount) AS AmountTotal
FROM MyMonthlyValues
GROUP BY [Year], [Month], Area, Product WITH ROLLUP

To restrict to the current month you could do

SELECT CASE WHEN (GROUPING([Year]) = 1) THEN 'All' ELSE CAST([Year] AS
CHAR(5)) END AS [Year],
CASE WHEN (GROUPING([Month]) = 1) THEN 'All' ELSE CAST([Month] AS CHAR(4))
END AS [Month],
CASE WHEN (GROUPING([Area]) = 1) THEN 'All' ELSE [Area]  END AS [Area],
CASE WHEN (GROUPING([Product]) = 1) THEN 'All' ELSE [Product] END AS
[Product],
SUM(Amount) AS AmountTotal
FROM MyMonthlyValues
WHERE [Month] = MONTH(GETDATE()) AND [Year] = YEAR(GetDate())
GROUP BY [Year], [Month], Area, Product WITH ROLLUP

You can process the rows on the client if you don't the format you
specified. Alternatively it is possible to do:

CREATE VIEW MyMonthlyTotals AS
SELECT [Year], [Month], [Area], [Product], SUM(Amount) As MonthTotal
FROM MyMonthlyValues
GROUP BY [Year], [Month], [Area], [Product]

SELECT A.[Year], A.[Month], A.[Area], A.[Product], A.[MonthTotal], ( SELECT
SUM(M.[MonthTotal]) FROM MyMonthlyTotals M WHERE A.[Year] = M.[Year] AND
A.[Month] >= M.[Month] AND A.[Area] = M.[Area] AND A.[Product] = M.[Product]
) AS AnnualTotal
FROM MyMonthlyTotals  A
WHERE A.[Month] = MONTH(GETDATE())
AND A.[Year] = YEAR(GetDate())
ORDER BY A.[Year], A.[Month], A.[Area], A.[Product]

You may need a Products, Areas and possibly a Calendar Table (see
http://www.aspfaq.com/show.asp?id=2519) to OUTER JOIN to, so that all
products, areas, months are displayed in case data is missing for certain
values.

e.g.
CREATE TABLE Products ( ProductId int NOT NULL IDENTITY(1,1), Product
char(4) )

INSERT INTO Products ( Product )
SELECT 'Book'
UNION ALL SELECT 'Pen'

CREATE TABLE Areas( AreaId int NOT NULL IDENTITY(1,1), Area char(2) )

INSERT INTO Areas ( Area )
SELECT 'CA'
UNION ALL SELECT 'NY'

John
Show quote
"OKLover" wrote:

> Help! CUBE? ROLLUP? or COMPUTE BY?
>
>
> Giving a table's content as below...
>
> Date        Area    Product        Amount
> ------------------------------------------------------------------------------
> 2005/07/23    CA    Book        150
> 2005/07/29    NY    Pen        70
> 2005/08/03    CA    Pen        500
> 2005/08/04    CA    Book        200
> 2005/08/05    NY    Book        270
>
>
> May i ask how to get the result as below?
>
> Area    Book            Book            Pen            Pen
> -------------------------------------------------------------------------------------
> CA    SUM(Book_CA_thisMonth)    SUM(Book_CA_thisyear)    SUM(Pen_CA_thisMonth)    SUM(Pen_CA_thisyear)
> NY    SUM(Book_NY_thisMonth)    SUM(Book_NY_thisyear)    SUM(Pen_NY_thisMonth)    SUM(Pen_NY_thisyear)
>
> Should i use CUBE? ROLLUP? or COMPUTE BY? What's the correct SELECT syntax?
Author
14 Aug 2005 1:57 AM
OKLover
What a MVP likes John Bell should to be respected. you do so much. :)

As your suggestion, i got 3 SELECT results as below:

Year    Month    Area    Product    AmountTotal
------------------------------------------------------------------------
2005     7       CA     Book    150
2005     7       CA     All     150
2005     7       NY     Pen     70
2005     7       NY     All     70
2005     7       All    All     220
2005     8       CA     Book    200
2005     8       CA     Pen     500
2005     8       CA     All     700
2005     8       NY     Book    270
2005     8       NY     All     270
2005     8       All    All     970
2005     All     All    All     1190
All      All     All    All     1190




Year    Month    Area    Product    AmountTotal
----------------------------------------------------------------------
2005     8       CA     Book    200
2005     8       CA     Pen     500
2005     8       CA     All     700
2005     8       NY     Book    270
2005     8       NY     All     270
2005     8       All    All     970
2005     All     All    All     970
All      All     All    All     970



Year    Month    Area    Product    MonthT    AnnualT
----------------------------------------------------------------------------
2005    8    CA    Book    200    350
2005    8    CA    Pen     500    500
2005    8    NY    Book    270    270


Is it possible to get the results like this:

              Book            Pen
-------------------------------------------------
CA |   200   350      500   500      
NY |   270   270      Null   Null


Total with 4 columns and 2 rows excluding the Product and Area label.
Author
14 Aug 2005 7:35 AM
John Bell
Hi

I would have hoped that you would have taken the suggestions further,
progressing further with the scripts and taken on some of the suggestions,
such as using a product, area and calendar table you can "fill in the gaps"
such as:

CREATE TABLE Calendar ( Month int, Year int, [Date] datetime )

DECLARE @basedate datetime
SET @basedate  = '20050101'

INSERT Calendar ( Month, Year, [Date] )
SELECT
MONTH(DATEADD(m,i,@basedate)),Year(DATEADD(m,i,@basedate)),DATEADD(m,i,@basedate)
FROM ( SELECT 1 AS i
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
UNION ALL SELECT 10
UNION ALL SELECT 11
UNION ALL SELECT 12 ) A

SELECT R.[Area], P.[Product], A.[MonthTotal], ( SELECT
SUM(M.[MonthTotal]) FROM MyMonthlyTotals M WHERE C.[Year] = M.[Year] AND
C.[Month] >= M.[Month] AND R.[Area] = M.[Area] AND P.[Product] = M.[Product]
) AS AnnualTotal
FROM Calendar C
CROSS JOIN [Products] P
CROSS JOIN [Areas] R
LEFT JOIN MyMonthlyTotals  A ON A.Product = P.Product AND C.[Month] =
A.[Month] AND  C.[Year] = A.[Year] AND R.[Area] = A.[Area]
WHERE C.[Month] = 8
AND C.[Year] = 2005
ORDER BY R.[Area], P.[Product]

This will give

Area Product MonthTotal  AnnualTotal
---- ------- ----------- -----------
CA   Book    200         350
CA   Pen     500         500
NY   Book    270         270
NY   Pen     NULL        70

In the previous post I said to get into your exact format it is best to do
it on the client, but it is possible using SQL, and there are many posts on
how to CROSSTAB or PIVOT your results such as http://tinyurl.com/7hfet where
if you had read the links such as
http://www.windowsitpro.com/SQLServer/Article/ArticleID/15608/15608.html you
should have come up with:

SELECT [Area], SUM(CASE WHEN [Product] = 'Book' THEN MonthTotal ELSE 0 END)
AS [Book Month],
SUM(CASE WHEN [Product] = 'Book' THEN AnnualTotal ELSE 0 END) AS [Book Year],
SUM(CASE WHEN [Product] = 'Pen' THEN MonthTotal ELSE 0 END) AS [Pen Month],
SUM(CASE WHEN [Product] = 'Pen' THEN AnnualTotal ELSE 0 END) AS [Pen Year]
FROM ( SELECT R.[Area], P.[Product], A.[MonthTotal], ( SELECT
SUM(M.[MonthTotal]) FROM MyMonthlyTotals M WHERE C.[Year] = M.[Year] AND
C.[Month] >= M.[Month] AND R.[Area] = M.[Area] AND P.[Product] = M.[Product]
) AS AnnualTotal
FROM Calendar C
CROSS JOIN [Products] P
CROSS JOIN [Areas] R
LEFT JOIN MyMonthlyTotals  A ON A.Product = P.Product AND C.[Month] =
A.[Month] AND  C.[Year] = A.[Year] AND R.[Area] = A.[Area]
WHERE C.[Month] = 8
AND C.[Year] = 2005 ) D
GROUP BY [Area]
ORDER BY [Area]

John

Show quote
"OKLover" wrote:

> What a MVP likes John Bell should to be respected. you do so much. :)
>
> As your suggestion, i got 3 SELECT results as below:
>
> Year    Month    Area    Product    AmountTotal
> ------------------------------------------------------------------------
> 2005     7       CA     Book    150
> 2005     7       CA     All     150
> 2005     7       NY     Pen     70
> 2005     7       NY     All     70
> 2005     7       All    All     220
> 2005     8       CA     Book    200
> 2005     8       CA     Pen     500
> 2005     8       CA     All     700
> 2005     8       NY     Book    270
> 2005     8       NY     All     270
> 2005     8       All    All     970
> 2005     All     All    All     1190
> All      All     All    All     1190
>
>
>
>
> Year    Month    Area    Product    AmountTotal
> ----------------------------------------------------------------------
> 2005     8       CA     Book    200
> 2005     8       CA     Pen     500
> 2005     8       CA     All     700
> 2005     8       NY     Book    270
> 2005     8       NY     All     270
> 2005     8       All    All     970
> 2005     All     All    All     970
> All      All     All    All     970
>
>
>
> Year    Month    Area    Product    MonthT    AnnualT
> ----------------------------------------------------------------------------
> 2005    8    CA    Book    200    350
> 2005    8    CA    Pen     500    500
> 2005    8    NY    Book    270    270
>
>
> Is it possible to get the results like this:
>
>               Book            Pen
> -------------------------------------------------
> CA |   200   350      500   500      
> NY |   270   270      Null   Null
>
>
> Total with 4 columns and 2 rows excluding the Product and Area label.
Author
14 Aug 2005 12:50 PM
OKLover
THANK YOU VERY MUCH !!!

AddThis Social Bookmark Button