| Author |
Topic |
|
JohnC28
Starting Member
11 Posts |
Posted - 2008-03-07 : 05:01:50
|
| I have a table:ID int, AreaID int, SaleAmount float, SaleDate smalldatetimeAreaID is an foreign key to a second table of heirarchical area data:ID int, ParentId int, AreaName nvarchar.The heirarchy varies in depth for different parts of the country - sometimes 3 levels deep, sometimes up to six.My problem is this: how do a construct a sproc that will allow me to pass in any area id and then return one or more result sets with all the child data of that area id grouped (to allow a SUM() of the sales data and a MIN() of the dates) by EACH LEVEL of the heirarchy?Sales data only exists in the bottom one or two levels.I've tried looking at CTEs but can't seem to crack the problem. I got close with a WHILE loop, but that kept grouping the data at the same level.....ThanksJohnExpected output from this data if, say, I passed in 1 (the National level)'National', 47.81, 20-Feb-08'Super Region A', 37.81, 21-Feb-08'Region 1', 16.81, 21-Feb-08'Region 2', 21.00, 22-Feb-08'Sub Region 1', 8.81, 21-Feb-08'Sub Region 2', 8.00, 22-Feb-08'Sub Region 3', 7.70, 23-Feb-08'Sub Region 4', 12.30, 22-Feb-08and so on. Note that it doesn't have to be one table - each level could come back as a separate table (in fact, that might be helpful).If I passed in 3 I'd get'Region 1', 16.81, 21-Feb-08'Sub Region 1', 8.81, 21-Feb-08'Sub Region 2', 8.00, 22-Feb-08(NB these results are just typed in, so forgive typos please, and the sums and min dates are not necissarily the same as from the sampledata below)CREATE TABLE [dbo].[SalesData]( [ID] [bigint] IDENTITY(1,1) NOT NULL, [AreaID] [int] NULL, [SalesDate] [smalldatetime] NULL , [SalesAmount] [float] NULL) CREATE TABLE [dbo].[SalesAreas]( [ID] [int] IDENTITY(1,1) NOT NULL, [ParentID] [int] NOT NULL , [Name] [nvarchar](64) NOT NULL) DECLARE @ID intDECLARE @ID2 intDECLARE @ID3 int INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( 0, 'National') --1SELECT @ID = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID, 'Super Region A')--2SELECT @ID2 = @@IDENTITY INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID2, 'Region 1') --3SELECT @ID3 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 1') --4INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 2') --5 INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID2, 'Region 2') --6SELECT @ID3 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 3') --7INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 4') --8 INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID, 'Super Region B')--9SELECT @ID2 = @@IDENTITY INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID2, 'Region 3') --10SELECT @ID3 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 5') --11INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 6') --12INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 7') --13 INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID2, 'Region 4') --14SELECT @ID3 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 8') --15INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 9') --16INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 10') --17INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 11') --18 INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (4, DATEADD(d,-5, GETDATE()), 3.49)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (4, DATEADD(d,-6, GETDATE()), 2.81)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (5, DATEADD(d,-8, GETDATE()), 4.14)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (5, DATEADD(d,-9, GETDATE()), 1.89)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (5, DATEADD(d,-2, GETDATE()), 1.02)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (5, DATEADD(d,-3, GETDATE()), 3.13)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (7, DATEADD(d,-4, GETDATE()), 5.12)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (7, DATEADD(d,-4, GETDATE()), 6.17)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (7, DATEADD(d,-1, GETDATE()), 3.49)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (8, DATEADD(d,-4, GETDATE()), 4.29)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (8, DATEADD(d,-5, GETDATE()), 4.46)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (11, DATEADD(d,-6, GETDATE()), 3.33)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (11, DATEADD(d,-1, GETDATE()), 3.92)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (12, DATEADD(d,-7, GETDATE()), 5.89)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (13, DATEADD(d,-5, GETDATE()), 6.16)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (13, DATEADD(d,-3, GETDATE()), 3.34)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (15, DATEADD(d,-2, GETDATE()), 2.61)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (15, DATEADD(d,-3, GETDATE()), 5.12)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (16, DATEADD(d,-4, GETDATE()), 8.28)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (17, DATEADD(d,-5, GETDATE()), 2.44) |
|
|
dataguru1971
Master Smack Fu Yak Hacker
1464 Posts |
Posted - 2008-03-07 : 10:26:20
|
Maybe I missed something but:ID ParentID [Name]1 0 National2 1 Super Region A3 2 Region 14 3 Sub Region 15 3 Sub Region 26 2 Region 27 6 Sub Region 38 6 Sub Region 49 1 Super Region B10 9 Region 311 10 Sub Region 512 10 Sub Region 613 10 Sub Region 714 9 Region 415 14 Sub Region 816 14 Sub Region 917 14 Sub Region 1018 14 Sub Region 11 ID AreaID SalesDate SalesAmount1 4 2008-03-02 10:20:00 3.492 4 2008-03-01 10:20:00 2.813 5 2008-02-28 10:20:00 4.144 5 2008-02-27 10:20:00 1.895 5 2008-03-05 10:20:00 1.026 5 2008-03-04 10:20:00 3.137 7 2008-03-03 10:20:00 5.128 7 2008-03-03 10:20:00 6.179 7 2008-03-06 10:20:00 3.4910 8 2008-03-03 10:20:00 4.2911 8 2008-03-02 10:20:00 4.4612 11 2008-03-01 10:20:00 3.3313 11 2008-03-06 10:20:00 3.9214 12 2008-02-29 10:20:00 5.8915 13 2008-03-02 10:20:00 6.1616 13 2008-03-04 10:20:00 3.3417 15 2008-03-05 10:20:00 2.6118 15 2008-03-04 10:20:00 5.1219 16 2008-03-03 10:20:00 8.2820 17 2008-03-02 10:20:00 2.44 How are those tables supposed to connect?What can do is get your grandtotal and union to sub-group total etcSelect 'Grand Total', Sum(SalesAmount), min(SalesDate)FROM SalesDataUnionSelect [Name], Sum(SalesAmount),min(SalesDate)FROM SalesArea {somehow join) SalesData on {linking fields}Where SalesArea = {subareacode?}Group by [Name]UNION ---and so forth. Poor planning on your part does not constitute an emergency on my part. |
 |
|
|
JohnC28
Starting Member
11 Posts |
Posted - 2008-03-07 : 10:42:00
|
| Hi dataguruThe link is AreaID in the sales table - FK to ID in the SalesArea table (your 2nd field is incorrectly called AreaId - that should be ParentID).That join is clearly straightforward.My problem is how to group by higher up the heirarchy. So if I send in 1 to a SPROC, I'd want data grouped at national level (just one row), Super Regional Level (2 rows in my sample data), Regional Level(4 rows of output), and finally sub-regional level.However, the sales data may only be at sub-regional level and that's the issue I can't get round. How do I GROUP BY in a recursive fashion down to the level that actually holds the join data. |
 |
|
|
JohnC28
Starting Member
11 Posts |
Posted - 2008-03-07 : 11:49:43
|
| This should be (my caps):ID PARENTID [Name]1 0 National2 1 Super Region A3 2 Region 14 3 Sub Region 15 3 Sub Region 2etcID AreaID SalesDate SalesAmount1 4 2008-03-02 10:20:00 3.492 4 2008-03-01 10:20:00 2.813 5 2008-02-28 10:20:00 4.14so AreaID joins to ID in the first table, and ID joins to ParentID in a self join all the way up to 0.Sorry not to be clear about that :) |
 |
|
|
JohnC28
Starting Member
11 Posts |
Posted - 2008-03-07 : 11:53:02
|
| Just to be absolutely clear Row 2 of the SalesData table would join to 'Sub Region 1' from the Area table.'Sub Region 1' would join to 'Region 1' through a self-join, 'Region 1' to 'Super Region A' and then to 'National'.A GROUP BY at National level would SUM/AVG all data in the SalesData table, a GROUP by at the next level (any child with 'National' as the ParentID would SUm/AVG all data in the descendants of each 2 level child and so forth.Does that help? |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-03-07 : 12:30:43
|
Or use the WITH CUBE or WITH ROLLUP to get all data in one operation. E 12°55'05.25"N 56°04'39.16" |
 |
|
|
dataguru1971
Master Smack Fu Yak Hacker
1464 Posts |
Posted - 2008-03-07 : 17:02:37
|
I am not sure how to use those functions, nor in this scenario...But I did get the desired results using the below. (Your code is at the top..there was a type in one the table names..this runs and produces the results) CREATE TABLE [dbo].[SalesData]([ID] [bigint] IDENTITY(1,1) NOT NULL,[AreaID] [int] NULL,[SalesDate] [smalldatetime] NULL ,[SalesAmount] [float] NULL)CREATE TABLE [dbo].[SalesArea]([ID] [int] IDENTITY(1,1) NOT NULL,[ParentID] [int] NOT NULL ,[Name] [nvarchar](64) NOT NULL)DECLARE @ID intDECLARE @ID2 intDECLARE @ID3 intINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( 0, 'National') --1SELECT @ID = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID, 'Super Region A')--2SELECT @ID2 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID2, 'Region 1') --3SELECT @ID3 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 1') --4INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 2') --5INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID2, 'Region 2') --6SELECT @ID3 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 3') --7INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 4') --8INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID, 'Super Region B')--9SELECT @ID2 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID2, 'Region 3') --10SELECT @ID3 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 5') --11INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 6') --12INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 7') --13INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID2, 'Region 4') --14SELECT @ID3 = @@IDENTITYINSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 8') --15INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 9') --16INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 10') --17INSERT INTO SalesArea ([ParentID], [Name]) VALUES ( @ID3, 'Sub Region 11') --18INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (4, DATEADD(d,-5, GETDATE()), 3.49)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (4, DATEADD(d,-6, GETDATE()), 2.81)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (5, DATEADD(d,-8, GETDATE()), 4.14)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (5, DATEADD(d,-9, GETDATE()), 1.89)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (5, DATEADD(d,-2, GETDATE()), 1.02)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (5, DATEADD(d,-3, GETDATE()), 3.13)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (7, DATEADD(d,-4, GETDATE()), 5.12)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (7, DATEADD(d,-4, GETDATE()), 6.17)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (7, DATEADD(d,-1, GETDATE()), 3.49)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (8, DATEADD(d,-4, GETDATE()), 4.29)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (8, DATEADD(d,-5, GETDATE()), 4.46)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (11, DATEADD(d,-6, GETDATE()), 3.33)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (11, DATEADD(d,-1, GETDATE()), 3.92)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (12, DATEADD(d,-7, GETDATE()), 5.89)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (13, DATEADD(d,-5, GETDATE()), 6.16)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (13, DATEADD(d,-3, GETDATE()), 3.34)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (15, DATEADD(d,-2, GETDATE()), 2.61)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (15, DATEADD(d,-3, GETDATE()), 5.12)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (16, DATEADD(d,-4, GETDATE()), 8.28)INSERT INTO SalesData (AreaID, SalesDate, SalesAmount) VALUES (17, DATEADD(d,-5, GETDATE()), 2.44)---------Select Roll.ID,Roll.Name, Sum(SalesAmount) as Sales, min(SalesDate) as DateFROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.ID = area.ID) total on total.ParentID = area.ID JOIN SalesArea roll on area.ParentID = roll.ID GROUP by Roll.ID,Roll.Name--UNION ALLSelect area.ID,area.Name, Sum(SalesAmount) as Sales, min(SalesDate) as DateFROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.AreaID = area.ID) total on total.ParentID = area.ID Group by area.ID,area.NameUNIONSelect total.ID,Total.Name, Sum(SalesAmount) as Sales, min(SalesDate) as DateFROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.AreaID = area.ID) total on total.ParentID = area.ID Group by total.ID,Total.Name/*Results1 National 17.45 2008-02-28 16:31:002 Super Region A 14.2 2008-02-27 16:31:003 Region 1 16.48 2008-02-27 16:31:004 Sub Region 1 6.3 2008-03-01 16:31:005 Sub Region 2 10.18 2008-02-27 16:31:006 Region 2 23.53 2008-03-02 16:31:007 Sub Region 3 14.78 2008-03-03 16:31:008 Sub Region 4 8.75 2008-03-02 16:31:009 Super Region B 28.94 2008-03-01 16:31:0010 Region 3 22.64 2008-02-29 16:31:0011 Sub Region 5 7.25 2008-03-01 16:31:0012 Sub Region 6 5.89 2008-02-29 16:31:0013 Sub Region 7 9.5 2008-03-02 16:31:0014 Region 4 18.45 2008-03-02 16:31:0015 Sub Region 8 7.73 2008-03-04 16:31:0016 Sub Region 9 8.28 2008-03-03 16:31:0017 Sub Region 10 2.44 2008-03-02 16:31:00*/Drop Table SalesDataDrop Table SalesArea I would like to see how the CUBE and ROLLUP could be used, or a cleaner way to do this. I was just playing around with it. Poor planning on your part does not constitute an emergency on my part. |
 |
|
|
JohnC28
Starting Member
11 Posts |
Posted - 2008-03-07 : 19:56:54
|
| Hi dataguruThanks for sticking with this.The result certainly looks good.I'll give the code a try in the morning when I'm a bit more focussed (it's 1am here) and let you know how that works. |
 |
|
|
dataguru1971
Master Smack Fu Yak Hacker
1464 Posts |
Posted - 2008-03-07 : 20:14:36
|
okay. I like learning how to do new stuff...I wish I had picked up that relational self join thing sooner. Makes sense now though...I am gonna keep playing with it to see if I can figure out the rollup and Cube stuff. Poor planning on your part does not constitute an emergency on my part. |
 |
|
|
JohnC28
Starting Member
11 Posts |
Posted - 2008-03-08 : 07:09:44
|
| It works!And performance seems good to.The only issues now are (a) What happens for areas with greater than three depths(b) How do I get just part of the tree (say the bottom two levels)If anyone's got any thoughts, I'd be pleased to hear them - in the meantime I will persue.Thanks for the input dataguru! |
 |
|
|
dataguru1971
Master Smack Fu Yak Hacker
1464 Posts |
Posted - 2008-03-08 : 08:09:16
|
You can comment out part of my query to get just the parts.If you do each segment individually you can see how they look. The way this is written, it should work even with more levels.To get different levels by passing a paramenter you may have to add some conditions. Since the areaId, ParentID , and ID columns are used together in the output...you can add the other levels as "sub level" or something to the query.I will post back with something on that. Poor planning on your part does not constitute an emergency on my part. |
 |
|
|
dataguru1971
Master Smack Fu Yak Hacker
1464 Posts |
Posted - 2008-03-08 : 08:40:36
|
What it does is in each part of the UNION, it applies the @LEVEL paramenter to that sets ID column. For example, the first section does the National,and Super Regions and by itself produces:1 National 17.45 2008-02-29 08:28:002 Super Region A 14.2 2008-02-28 08:28:009 Super Region B 28.94 2008-03-02 08:28:00 Which represents the PARENTID column from the Area table, but wrapped inside the derived table for the self join and aliased as ROLL.The 2nd set produces this by itself, where The ID column in this part is the SalesArea.ID column limited to the derived table which joins area and sales on Derived(joins on SalesData.AreaID to Area.ID).ParentID = Area.ID 3 Region 1 16.48 2008-02-28 08:28:006 Region 2 23.53 2008-03-03 08:28:0010 Region 3 22.64 2008-03-01 08:28:0014 Region 4 18.45 2008-03-03 08:28:00 The 3rd set produces this by itself, where The ID column in this part is the lowest levelthe last part produces:4 Sub Region 1 6.3 2008-03-02 08:28:005 Sub Region 2 10.18 2008-02-28 08:28:007 Sub Region 3 14.78 2008-03-04 08:28:008 Sub Region 4 8.75 2008-03-03 08:28:0011 Sub Region 5 7.25 2008-03-02 08:28:0012 Sub Region 6 5.89 2008-03-01 08:28:0013 Sub Region 7 9.5 2008-03-03 08:28:0015 Sub Region 8 7.73 2008-03-05 08:28:0016 Sub Region 9 8.28 2008-03-04 08:28:0017 Sub Region 10 2.44 2008-03-03 08:28:00 I then just order by the resulting ID column to get the unique list and levels you asked for.this part would allow for filtering for levels, in this case filtering for the appropriate ID column (although one that is NOT returned in the data)Declare @Level intSET @LEVEL = 1Select Roll.ID,Roll.Name, Sum(SalesAmount) as Sales, min(SalesDate) as DateFROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.ID = area.ID) total on total.ParentID = area.ID JOIN SalesArea roll on area.ParentID = roll.IDWhere Roll.ID = @LEVEL GROUP by Roll.ID,Roll.NameUNION ALLSelect area.ID,area.Name, Sum(SalesAmount) as Sales, min(SalesDate) as Date FROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.AreaID = area.ID) total on total.ParentID = area.ID Where Total.ID = @LEVEL Group by area.ID,area.Name UNIONSelect total.ID,Total.Name, Sum(SalesAmount) as Sales, min(SalesDate) as DateFROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.AreaID = area.ID) total on total.ParentID = area.ID Where area.ID = @LEVEL Group by total.ID,Total.Name/*Results where @LEVEL = 32 Super Region A 2.91 2008-02-28 08:19:004 Sub Region 1 6.3 2008-03-02 08:19:005 Sub Region 2 10.18 2008-02-28 08:19:00@LEVEl = 53 Region 1 10.18 2008-02-28 08:19:00@LEVEL = 11 National 17.45 2008-02-29 08:23:00@LEVEL = 1415 Sub Region 8 7.73 2008-03-05 08:24:0016 Sub Region 9 8.28 2008-03-04 08:24:0017 Sub Region 10 2.44 2008-03-03 08:24:00@LEVEL = 22 Super Region A 14.2 2008-02-28 08:25:00*/ Poor planning on your part does not constitute an emergency on my part. |
 |
|
|
dataguru1971
Master Smack Fu Yak Hacker
1464 Posts |
Posted - 2008-03-08 : 08:52:29
|
Here is another alternative. You can remove the unions and do a filter for which sub-set you want. At this point I think you can get the idea of how you might be able to get a sproc out of this to return desired results.Declare @Level intSET @LEVEL = 1IF @LEVEL = 1Select Roll.ID,Roll.Name, Sum(SalesAmount) as Sales, min(SalesDate) as DateFROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.ID = area.ID) total on total.ParentID = area.ID JOIN SalesArea roll on area.ParentID = roll.IDGROUP by Roll.ID,Roll.NameIF @LEVEL = 2Select area.ID,area.Name, Sum(SalesAmount) as Sales, min(SalesDate) as Date FROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.AreaID = area.ID) total on total.ParentID = area.ID Where Total.ID = @LEVEL Group by area.ID,area.Name IF @LEVEL = 3Select total.ID,Total.Name, Sum(SalesAmount) as Sales, min(SalesDate) as DateFROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.AreaID = area.ID) total on total.ParentID = area.ID Where area.ID = @LEVEL Group by total.ID,Total.Name Poor planning on your part does not constitute an emergency on my part. |
 |
|
|
JohnC28
Starting Member
11 Posts |
Posted - 2008-03-08 : 19:45:05
|
| There's something that perplexes me..... (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area this line >>>>> on data.ID = area.ID) totalThere is no relationship between the primary key of the area table and the primary key of the data table.And yet this seems to work.Why? |
 |
|
|
dataguru1971
Master Smack Fu Yak Hacker
1464 Posts |
Posted - 2008-03-08 : 20:09:50
|
Sure there is.It is just a trick to join the tables and get the appropriate parent region. You can see it by looking at the subquery aggregate results, and then referring to the actual alias'd table "total" that your question refers to (which is the 2nd part of the UNION)the results from that subset as I wrote it are:ID Name Sales Date3 Region 1 16.48 2008-02-28 19:56:006 Region 2 23.53 2008-03-03 19:56:0010 Region 3 22.64 2008-03-01 19:56:0014 Region 4 18.45 2008-03-03 19:56:00 the subquery alias "total" itself produces:ID AreaID SalesDate SalesAmount ParentID Name4 4 2008-03-03 20:00:00 3.49 3 Sub Region 14 4 2008-03-02 20:00:00 2.81 3 Sub Region 15 5 2008-02-29 20:00:00 4.14 3 Sub Region 25 5 2008-02-28 20:00:00 1.89 3 Sub Region 25 5 2008-03-06 20:00:00 1.02 3 Sub Region 25 5 2008-03-05 20:00:00 3.13 3 Sub Region 27 7 2008-03-04 20:00:00 5.12 6 Sub Region 37 7 2008-03-04 20:00:00 6.17 6 Sub Region 37 7 2008-03-07 20:00:00 3.49 6 Sub Region 38 8 2008-03-04 20:00:00 4.29 6 Sub Region 48 8 2008-03-03 20:00:00 4.46 6 Sub Region 411 11 2008-03-02 20:00:00 3.33 10 Sub Region 511 11 2008-03-07 20:00:00 3.92 10 Sub Region 512 12 2008-03-01 20:00:00 5.89 10 Sub Region 613 13 2008-03-03 20:00:00 6.16 10 Sub Region 713 13 2008-03-05 20:00:00 3.34 10 Sub Region 715 15 2008-03-06 20:00:00 2.61 14 Sub Region 815 15 2008-03-05 20:00:00 5.12 14 Sub Region 816 16 2008-03-04 20:00:00 8.28 14 Sub Region 917 17 2008-03-03 20:00:00 2.44 14 Sub Region 10 So AreaID = ID for this purpose...merely putting the data together so I could connect ParentID back into the Salesarea.ID field.when wrapped into this:Select area.ID,area.Name, Sum(SalesAmount) as Sales, min(SalesDate) as Date FROM SalesArea area join (Select area.ID,AreaID,SalesDate,SalesAmount,ParentID,[Name] FROM SalesData data join SalesArea area on data.AreaID = area.ID) total on total.ParentID = area.ID Group by area.ID,area.Name I get the ParentID from the above subset, and link back to the salesarea table to get the [Name] associated with THAT parentID (from the alias'ed table called "total")It was the only way it would produce the correct subset (above, in summary for the Regions 1,2,3,4)I am sure there are better ways to do this, but this one was a neat thing to figure out. Poor planning on your part does not constitute an emergency on my part. |
 |
|
|
|
|
|