Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
rythm123us
Starting Member
27 Posts |
Posted - 2005-09-11 : 22:40:21
|
| I am trying to display Hieracrhial Data. I am running into trouble when I try to display a PRODUCT multiple times when it has different PRICE.Please read below to see what I mean:tbl_Category:CategoryID ParentID Category Lineage SortOrder1 0 All 1 02 1 Beer 1.1 13 2 Domestic 1.1.1 237 1 Wine 1.4 3838 37 Domestic 1.4.1 3939 38 California 1.4.1.1 40tbl_Sales:SalesID ProductID Quantity Price Cost20935 1554 1 6.99 4.9120935 721 1 10.99 820934 786 1 9.99 7.3520934 786 2 9.99 7.3520933 1554 1 6.99 4.9120933 1554 1 5.99 4.91tbl_Products:ProductID Product CategoryID1554 Woodbridge Chardonnay, 750 ml 39721 SHARPE HILL RED SERAPH, 750 ml 38786 BUD , 12 oz 12 pack Bottle(s) 3The Result I would like to seeSalesID CategoryID ParentID CategoryText Lineage SortOrder Quantity Price Cost20935 1 0 All 1 0 2 17.98 12.9120935 37 1 Wine 1.4 3800 2 17.98 12.9120935 38 37 Domestic 1.4.1 3900 2 17.98 12.9120935 -1 38 SHARPE HILL RED SERAPH, 750 ml X.1.4.1 3901 1 10.99 820935 39 38 California 1.4.1.1 4000 1 6.99 4.9120935 -1 39 Woodbridge Chardonnay, 750 ml X.1.4.1.1 4001 1 6.99 4.9120934 1 0 All 1 0 3 29.97 22.0520934 2 1 Beer 1.1 100 3 29.97 22.0520934 3 2 Domestic 1.1.1 200 3 29.97 22.0520934 -1 3 BUD , 12 oz 12 pack Bottle(s) X.1.1.1 201 3 29.97 22.0520933 1 0 All 1 0 2 12.98 9.8220933 37 1 Wine 1.4 3800 2 12.98 9.8220933 38 37 Domestic 1.4.1 3900 2 12.98 9.8220933 39 38 California 1.4.1.1 4000 2 12.98 9.8220933 -1 39 Woodbridge Chardonnay, 750 ml X.1.4.1.1 4001 1 6.99 4.9120933 -1 39 Woodbridge Chardonnay, 750 ml X.1.4.1.1 4001 1 5.99 4.91What I get is:SalesID CategoryID ParentID CategoryText Lineage SortOrder Quantity Price Cost20935 1 0 All 1 0 1 6.99 4.9120935 1 0 All 1 0 1 10.99 820935 37 1 Wine 1.4 3800 1 6.99 4.9120935 37 1 Wine 1.4 3800 1 10.99 820935 38 37 Domestic 1.4.1 3900 1 6.99 4.9120935 38 37 Domestic 1.4.1 3900 1 10.99 820935 -1 38 SHARPE HILL RED SERAPH, 750 ml X.1.4.1 3901 1 10.99 820935 39 38 California 1.4.1.1 4000 1 6.99 4.9120935 -1 39 Woodbridge Chardonnay, 750 ml X.1.4.1.1 4001 1 6.99 4.9120934 1 0 All 1 0 3 19.98 14.720934 2 1 Beer 1.1 100 3 19.98 14.720934 3 2 Domestic 1.1.1 200 3 19.98 14.720934 -1 3 BUD , 12 oz 12 pack Bottle(s) X.1.1.1 201 3 19.98 14.720933 1 0 All 1 0 2 12.98 9.8220933 37 1 Wine 1.4 3800 2 12.98 9.8220933 38 37 Domestic 1.4.1 3900 2 12.98 9.8220933 39 38 California 1.4.1.1 4000 2 12.98 9.8220933 -1 39 Woodbridge Chardonnay, 750 ml X.1.4.1.1 4001 1 5.99 4.9120933 -1 39 Woodbridge Chardonnay, 750 ml X.1.4.1.1 4001 1 6.99 4.91The Query:DECLARE @start smalldatetime, @end smalldatetime;SET @start = '9/10/05'SET @end = '9/11/05'SELECT *FROM(SELECT A.SalesID, CASE WHEN (A.GRP = 1) THEN C.CategoryID ELSE -1 END AS CategoryID, CASE WHEN (A.GRP = 1) THEN C.ParentID ELSE Max(A.ParentID) END AS ParentID, CASE WHEN (A.GRP = 1) THEN C.CategoryText ELSE A.Product END AS CategoryText, CASE WHEN (A.GRP = 1) THEN MAX(C.Lineage) ELSE MAX(A.Lineage) END AS Lineage, CASE WHEN (A.GRP = 1) THEN C.SortOrder * 100 ELSE MAX(A.SortOrder) END AS SortOrder, SUM(Quantity) AS Quantity, SUM(Price) AS Price, SUM(Cost) AS CostFROM tbl_Categories C RIGHT JOIN(SELECT SP.SalesID, MAX(P.CategoryID) AS ParentID, SUM(SP.Quantity) AS Quantity, SUM(SP.Price) AS Price, SUM(SP.Cost) AS Cost, CASE WHEN (GROUPING(P.Product) = 1) THEN CASE WHEN(C.Lineage IS NULL) THEN 0 ELSE Max(C.SortOrder) * 100 END ELSE (Max(C.SortOrder) * 100) + 1 END AS SortOrder, GROUPING(P.Product) as grp, GROUPING(SP.Price) as grp2, P.Product, CASE WHEN (GROUPING(P.Product) = 1) THEN C.Lineage ELSE 'X.' + C.Lineage END AS Lineage, CASE WHEN(GROUPING(P.Product) = 1) THEN CASE WHEN(C.Lineage IS NULL) THEN NULL ELSE MAX(C.CategoryText) END ELSE ISNULL(P.Product, 'UNKNOWN') END AS Category FROM tbl_Sales SP INNER JOIN tbl_Products P ON SP.ProductID = P.ProductID INNER JOIN tbl_Categories C ON P.CategoryID = C.CategoryID GROUP BY SP.SalesID, C.Lineage, P.Product, SP.Price WITH ROLLUP HAVING ((GROUPING(SP.Price) = 0) OR (GROUPING(SP.Price) = GROUPING(P.Product)))) AON SUBSTRING(A.Lineage, 0, LEN(C.Lineage) + 1) = C.LineageGROUP BY A.SalesID, C.ParentID, C.CategoryID, C.CategoryText, C.SortOrder, A.Product, A.GRP, A.Price) ZWHERE CategoryID IS NOT NULLORDER BY SalesID DESC, SortOrder, Price |
|
|
derrickleggett
Pointy Haired Yak DBA
4184 Posts |
Posted - 2005-09-12 : 01:43:12
|
I'll think about this a little bit more tomorrow when I'm not tired. I believe this will get you what you are wanting for right now.DECLARE @Category TABLE(CategoryID INT, ParentID INT, CategoryText VARCHAR(55), Lineage VARCHAR(55), SortOrder INT)INSERT @Category(CategoryID, ParentID, CategoryText, Lineage, SortOrder) SELECT 1, 0, 'All', '1', 0 UNION ALL SELECT 2, 1, 'Beer', '1.1', 1 UNION ALL SELECT 3, 2, 'Domestic', '1.1.1', 2 UNION ALL SELECT 37, 1, 'Wine', '1.4', 38 UNION ALL SELECT 38, 37, 'Domestic', '1.4.1', 39 UNION ALL SELECT 39, 38, 'California', '1.4.1.1', 40DECLARE @Sales TABLE(SalesID INT, ProductID INT, Quantity INT, Price MONEY, Cost MONEY)INSERT @Sales(SalesID, ProductID, Quantity, Price, Cost) SELECT 20935, 1554, 1, 6.99, 4.91 UNION ALL SELECT 20935, 721, 1, 10.99, 8 UNION ALL SELECT 20934, 786, 1, 9.99, 7.35 UNION ALL SELECT 20934, 786, 2, 9.99, 7.35 UNION ALL SELECT 20933, 1554, 1, 6.99, 4.91 UNION ALL SELECT 20933, 1554, 1, 5.99, 4.91 --UNION ALL-- SELECT 20933, 1554, 1, 5.99, 4.91DECLARE @Products TABLE(ProductID INT, Product VARCHAR(55), CategoryID INT)INSERT @Products(ProductID, Product, CategoryID) SELECT 1554, 'Woodbridge Chardonnay, 750 ml', 39 UNION ALL SELECT 721, 'SHARPE HILL RED SERAPH, 750 ml', 38 UNION ALL SELECT 786, 'BUD , 12 oz 12 pack Bottle(s)', 3SELECT SalesID, CategoryID, ParentID, CategoryText, Lineage, SortOrder, SUM(Quantity) AS Quantity, SUM(Price) AS Price, SUM(Cost) AS Cost, PriceMonitorFROM ( SELECT A.PriceMonitor, A.SalesID, CASE WHEN (A.GRP = 1) THEN C.CategoryID ELSE -1 END AS CategoryID, CASE WHEN (A.GRP = 1) THEN C.ParentID ELSE Max(ISNULL(A.ParentID,0)) END AS ParentID, CASE WHEN (A.GRP = 1) THEN C.CategoryText ELSE A.Product END AS CategoryText, CASE WHEN (A.GRP = 1) THEN MAX(ISNULL(C.Lineage,0)) ELSE MAX(A.Lineage) END AS Lineage, CASE WHEN (A.GRP = 1) THEN ISNULL(C.SortOrder,0) * 100 ELSE MAX(A.SortOrder) END AS SortOrder, SUM(Quantity) AS Quantity, SUM(Price) AS Price, SUM(Cost) AS Cost FROM @Category C RIGHT JOIN ( SELECT CASE WHEN P.CategoryID <> -1 THEN Price ELSE P.CategoryID END AS PriceMonitor, SP.SalesID, MAX(P.CategoryID) AS ParentID, SUM(SP.Quantity) AS Quantity, SUM(SP.Price*SP.Quantity) AS Price, SUM(SP.Cost*SP.Quantity) AS Cost, CASE WHEN (GROUPING(P.Product) = 1) THEN CASE WHEN(C.Lineage IS NULL) THEN 0 ELSE Max(C.SortOrder) * 100 END ELSE (Max(C.SortOrder) * 100) + 1 END AS SortOrder, GROUPING(P.Product) as grp, GROUPING(SP.Price) as grp2, P.Product AS Product, CASE WHEN (GROUPING(P.Product) = 1) THEN ISNULL(C.Lineage,0) ELSE 'X.' + ISNULL(C.Lineage,0) END AS Lineage, CASE WHEN(GROUPING(P.Product) = 1) THEN CASE WHEN(C.Lineage IS NULL) THEN 'UNKNOWN' ELSE MAX(C.CategoryText) END ELSE ISNULL(P.Product, 'UNKNOWN') END AS Category FROM @Sales SP INNER JOIN @Products P ON SP.ProductID = P.ProductID INNER JOIN @Category C ON P.CategoryID = C.CategoryID GROUP BY SP.SalesID, C.Lineage, P.Product, SP.Price, P.CategoryID WITH ROLLUP HAVING ((GROUPING(SP.Price) = 0) OR (GROUPING(SP.Price) = GROUPING(P.Product))) ) A ON SUBSTRING(A.Lineage, 0, LEN(C.Lineage) + 1) = C.Lineage GROUP BY A.SalesID, C.ParentID, C.CategoryID, C.CategoryText, C.SortOrder, A.Product, A.GRP, A.Price, A.PriceMonitor) ZWHERE CategoryID IS NOT NULL AND (CategoryID <> -1 OR PriceMonitor IS NOT NULL)GROUP BY SalesID, CategoryID, ParentID, CategoryText, Lineage, SortOrder, PriceMonitorORDER BY SalesID DESC, SortOrder, Price You had a few issues:1. You were eliminating NULLs by not having ISNULL around all your numeric aggregates. In most cases, this would still produce the same result, but it would be annoying for any application actually trying to use this.2. You weren't grouping out the individual product prices, so there was no way to differentiate between the same products with different prices.3. The top level of your query wasn't being aggregated, so you had a bunch of duplicates showing up, since anything not aggregated must appear in the GROUP BY clause. I might be wrong on this one since I'm tired. 4. I don't believe you were aggregating the prices correctly in the original derived table. I placed logic to multiply cost and price by the quantity.Forgive me if this is completely off base. I should have gone to bed earlier. lolMeanOldDBAderrickleggett@hotmail.comWhen life gives you a lemon, fire the DBA. |
 |
|
|
rythm123us
Starting Member
27 Posts |
Posted - 2005-09-12 : 10:25:06
|
Thanks it gives me the results I was looking for. I will take a better look at the query and my mistakes when I have sometime later this week.As far as your cooment 4quote: 4. I don't believe you were aggregating the prices correctly in the original derived table. I placed logic to multiply cost and price by the quantity.
This was done on purpose. The multiplication was not performed, so that the user can see the original Price of the Product and the Multiplication could be done on client side.If you are this good when you are tired, you must be GREAT when you are not.One more question was I on the right path with ROLLUP or was the query unnecessarily complicated. In simple terms is there a better way?Thanks for your help.If you could guide me towards some sites to increase my knowledge that would be veru helpful. |
 |
|
|
rythm123us
Starting Member
27 Posts |
Posted - 2005-09-12 : 21:52:00
|
| Actually I thought of something else and will try it on Thursday, but if you think this would be intriguing and would like to help that would be great.1. I would like to set the order in this manner.OrderID, CategoryID and then the Products will be ordered by SUM of Quantity for a Prodct, then PriceExample:INSERT @Products(ProductID, Product, CategoryID) SELECT 1555, 'Woodbridge Chardonnay, 1.5 L', 39INSERT @Sales(SalesID, ProductID, Quantity, Price, Cost)SELECT 20936, 1554, 2, 6.99, 4.91 UNION ALLSELECT 20936, 1555, 5, 11.99, 9.54 UNION ALLSELECT 20936, 1554, 4, 5.99, 4.91This would show up in this orderWoodbridge Chardonnay 750 ml, 4, 5.99, 4.91Woodbridge Chardonnay 750 ml, 2, 6.99, 4.91Woodbridge Chardonnay 1.5 L, 5, 11.99, 9.54It is in this order because the combined total of "Woodbridge Chardonnay 750 ml(ProductID:1554)" is greater than "Woodbridge Chardonnay 750 ml(ProductID: 1555)".2. Add 2 Percentage fields to the final query. One showing the Percentage of the Price within the given category and the other showing the Percentage of the Price compared to the entire Total(All). I have no idea how, but I will give it a try. Should be fun and frustrating at the same time.Thanks again...rythm |
 |
|
|
derrickleggett
Pointy Haired Yak DBA
4184 Posts |
Posted - 2005-09-12 : 22:37:15
|
| I might mess around with it this weekend just for fun. lolMeanOldDBAderrickleggett@hotmail.comWhen life gives you a lemon, fire the DBA. |
 |
|
|
rythm123us
Starting Member
27 Posts |
Posted - 2005-09-13 : 00:13:56
|
| When life gives you a lemon, fire the DBA.I don't get that |
 |
|
|
derrickleggett
Pointy Haired Yak DBA
4184 Posts |
Posted - 2005-09-13 : 11:38:37
|
| You haven't been a DBA very long have you?MeanOldDBAderrickleggett@hotmail.comWhen life gives you a lemon, fire the DBA. |
 |
|
|
rythm123us
Starting Member
27 Posts |
Posted - 2005-09-13 : 23:11:40
|
| I have done very little DBA work. I know a decent amount of SQL. Have worked with Oracle, SQL, and DB2. Mostly developing in all of these, but very little maintanenace. However, I always tried my best to understand the important topics to produce better results, and recently have been thinking of shifting my carrer from a Developer to a DBA. Any advice?? |
 |
|
|
rythm123us
Starting Member
27 Posts |
Posted - 2005-09-17 : 12:37:31
|
| i just created a new POST for the Percentage and SUM question. It is a different topic so I thought that would be best.http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=55311 |
 |
|
|
derrickleggett
Pointy Haired Yak DBA
4184 Posts |
Posted - 2005-09-17 : 15:44:22
|
| You have some interesting posts rythm. I wish that I had more time to spend on them. lol If you want to transition to a DBA, I would buy "Inside SQL Server" by Kalen Delaney, any book by Ken Henderson, the Performance Tuning Manual by Microsoft Press, and the 911 Admin book. There's always a demand for a really good DBA. Just determine to not be mediocre.Also, you need to really learn SQL and database relational theory. Learn how these things work on under the covers. You'll be a better DBA, developer, or programmer if you do.MeanOldDBAderrickleggett@hotmail.comWhen life gives you a lemon, fire the DBA. |
 |
|
|
|
|
|
|
|