![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
I'm trying to aggregate values and grouping the results by defined periods (6 month, 12 month, 18 month, and lifetime). I'd like to do this with one pass, but using a CASE statement did not aggregrate correctly. The results are more like 6 months, 7-12 months, and 13-18 months, 19-lifetime. I would like the results of the 12 month grouping to include all of the 6 month, the 18 month to include all of the 6 and 12 month grouping, etc. /**/ CASE WHEN pd.accountingdate > 0 THEN 'LIFE' WHEN pd.accountingdate BETWEEN '10/19/2004' AND '04/19/2007' THEN '18MONTH' WHEN pd.accountingdate BETWEEN '04/19/2006' AND '04/19/2007' THEN '12MONTH' WHEN pd.accountingdate BETWEEN '10/19/2006' AND '04/19/2007' THEN '06MONTH' ELSE NULL END |
#3
| |||
| |||
|
|
"Jeremy" <Jeremy (AT) discussions (DOT) microsoft.com> wrote in message news:79FBE5E0-E112-406A-B406-A5D19626FA96 (AT) microsoft (DOT) com... I'm trying to aggregate values and grouping the results by defined periods (6 month, 12 month, 18 month, and lifetime). I'd like to do this with one pass, but using a CASE statement did not aggregrate correctly. The results are more like 6 months, 7-12 months, and 13-18 months, 19-lifetime. I would like the results of the 12 month grouping to include all of the 6 month, the 18 month to include all of the 6 and 12 month grouping, etc. /**/ CASE WHEN pd.accountingdate > 0 THEN 'LIFE' WHEN pd.accountingdate BETWEEN '10/19/2004' AND '04/19/2007' THEN '18MONTH' WHEN pd.accountingdate BETWEEN '04/19/2006' AND '04/19/2007' THEN '12MONTH' WHEN pd.accountingdate BETWEEN '10/19/2006' AND '04/19/2007' THEN '06MONTH' ELSE NULL END In situations like this, you should post DDL, sample data, and the actual query. A non-working snippet of a query doesn't really help anyone understand the complete situation. Making some assumptions, I believe your problem is related to the use of a single column to represent different periods. The above case expression represents what? Is it the 6 month data, the 12 month data, ...? It can't represent more than one "attribute" - in this case, period. The solution is to generate separate period values. This can be done in one of two ways. Either you aggregate the periods as separate columns or you create a situation where you join the data to be aggregated to a table containing the periods. In the first example, you get period data as separate columns within the result set. In the second example, you get period data as separate rows. You decide which way you want to proceed. It will facilitate discussion to use either Pubs or Northwind for sample data and queries since most people have those available (and thus do not require the posting of DDL or sample data). |
#4
| |||
| |||
|
|
"Jeremy" <Jeremy (AT) discussions (DOT) microsoft.com> wrote in message news:79FBE5E0-E112-406A-B406-A5D19626FA96 (AT) microsoft (DOT) com... I'm trying to aggregate values and grouping the results by defined periods (6 month, 12 month, 18 month, and lifetime). I'd like to do this with one pass, but using a CASE statement did not aggregrate correctly. The results are more like 6 months, 7-12 months, and 13-18 months, 19-lifetime. I would like the results of the 12 month grouping to include all of the 6 month, the 18 month to include all of the 6 and 12 month grouping, etc. /**/ CASE WHEN pd.accountingdate > 0 THEN 'LIFE' WHEN pd.accountingdate BETWEEN '10/19/2004' AND '04/19/2007' THEN '18MONTH' WHEN pd.accountingdate BETWEEN '04/19/2006' AND '04/19/2007' THEN '12MONTH' WHEN pd.accountingdate BETWEEN '10/19/2006' AND '04/19/2007' THEN '06MONTH' ELSE NULL END In situations like this, you should post DDL, sample data, and the actual query. A non-working snippet of a query doesn't really help anyone understand the complete situation. Making some assumptions, I believe your problem is related to the use of a single column to represent different periods. The above case expression represents what? Is it the 6 month data, the 12 month data, ...? It can't represent more than one "attribute" - in this case, period. The solution is to generate separate period values. This can be done in one of two ways. Either you aggregate the periods as separate columns or you create a situation where you join the data to be aggregated to a table containing the periods. In the first example, you get period data as separate columns within the result set. In the second example, you get period data as separate rows. You decide which way you want to proceed. It will facilitate discussion to use either Pubs or Northwind for sample data and queries since most people have those available (and thus do not require the posting of DDL or sample data). |
#5
| |||
| |||
|
|
The results of the first query are affected by the sequence of the conditions in the CASE statement. And there's the rub. I'd like to have my results in rows because I'm aggregrating at least 20 columns and 4 periods would push it to 80 columns. Thanks for you help. |
#6
| |||
| |||
|
|
The results of the first query are affected by the sequence of the conditions in the CASE statement. And there's the rub. I'd like to have my results in rows because I'm aggregrating at least 20 columns and 4 periods would push it to 80 columns. Thanks for you help. The secret is that you need a table of periods - which you then join to your data while aggregating. This can be done in one pass since each "raw data row" joins once to each appropriate period. So a row for today joins to the 6 month period while a row from 10 months ago joins to both the 6 and 12 month periods (and so forth). The trick is to generate the period table - dynamically if needed. Below is a query (that can be used as a derived table) to do this. Obviously, the variable isn't actually required. You could create a table-valued function to do the same thing (especially if you needed to reuse this logic). declare @today datetime set @today = DATEDIFF(DAY, 0, CURRENT_TIMESTAMP) select @today, dateadd(month, -6, @today) union all select @today, dateadd(month, -12, @today) union all select @today, dateadd(month, -18, @today) You may need to adjust the logic depending on your definition of periods - the last day of the month (esp Feb in and out of a leap year) is always fun for these types of things. With the table of periods, you simply join to the transaction table where date of transaction is between the period start and end dates. |
![]() |
| Thread Tools | |
| Display Modes | |
| |