Author |
Topic |
jjw
Starting Member
9 Posts |
Posted - 2012-02-07 : 12:00:21
|
I'm trying to figure out how to group by some conditional business logic. I have Account Definitions and a summary table with metric data. Account Definitions are broken down into LOB (Line of Business) sub-groups.The key here is that 7 LOB's make up a larger logical group called "Merchandise". All 7 LOB's need to be defined (but not necessarily have data) in order to be summed up as Merchandise. If a LOB is not one of the 7, then it should be listed uniquely. 7 LOB's that make up Merchandise = 'AG','CH','EM','FC','MT','PA','PF')Here is the DDL for the 2 tables usedcreate table accountdefinition (account varchar(200),lob varchar(20))Create table summary (account varchar(200),lob varchar(20),volume1 int,volume2 int, volume3 int)Here is some sample data for the 2 tablesinsert into accountdefinition (account,lob)select 'Agway','AG' union allselect 'Agway','CH' union allselect 'Agway','CO' union allselect 'Agway','EM' union allselect 'Agway','FC' union allselect 'Agway','PA' union allselect 'Agway','PF' union allselect 'Cerestar','AG' union allselect 'Cerestar','CH' union allselect 'Cerestar','CO' union allselect 'Cerestar','EM' union allselect 'Cerestar','FC' union allselect 'Cerestar','MT' union allselect 'Cerestar','PA' union allselect 'Cerestar','PF' insert into summary (account,lob,volume1,volume2,volume3)select 'Agway','AG',2,3,55 union allselect 'Agway','AG',3,2,45 union allselect 'Cerestar','CO',1,1,100 union allselect 'Cerestar','EM',1,1,200Here is the query I wrote[CODE]select ad.account,'Merchandise' AS LOB,SUM(ac.volume1) as Volume_PYT,SUM(ac.volume2) as Volume_YTD,SUM(ac.volume3) as Volume_CYfrom accountdefinition adleft join SUMMARY ac on ad.account = ac.account and ad.lob = ac.lobwhere ad.lob in ('AG','CH','EM','FC','MT','PA','PF')group by ad.accountunionselect ad.account,ad.lob,SUM(ac.volume1) as Volume_PYT,SUM(ac.volume2) as Volume_YTD,SUM(ac.volume3) as Volume_CYfrom accountdefinition ad left join SUMMARY ac on ad.account = ac.account and ad.lob = ac.lobwhere ad.lob not in ('AG','CH','EM','FC','MT','PA','PF')group by ad.account,ad.lob[/CODE]Here are the results of my queryaccount LOB Volume_PYT Volume_YTD Volume_CYAgway CO NULL NULL NULLAgway Merchandise 5 5 100Cerestar CO 1 1 100Cerestar Merchandise 1 1 200Here are the expected resultsSince Agway doesn't have all 7 LOB's to make the logical group "Merchandise" (it is missing 'MT') we should seeAccount LOB Volume_PYT Volume_YTD Volume_CYAgway AG 5 5 100Agway CH null null nullAgway EM null null nullAgway FC null null nullAgway PA null null nullAgway PF null null nullAgway CO null null nullCerestar CO 1 1 100Cerestar Merchandise 1 1 200 |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-02-07 : 12:45:18
|
why Merchandise row didnt come for Agway? It has data against AG which is one mong LObs of merchandise------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
jjw
Starting Member
9 Posts |
Posted - 2012-02-07 : 13:05:30
|
quote: Originally posted by visakh16 why Merchandise row didnt come for Agway? It has data against AG which is one mong LObs of merchandise------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/
because Merchandise should only come up if Account has all 7 LOB's. In this case Agway only has 6 of the 7 LOB's that make up Merchandise, so they need to be listed individually.This is really the problem I'm having and maybe the Group By / Union is the right approach. Because if any of the LOB's are in Merchandise then a Merchandise row appears and I only want a Merchandise row to appear if ALL 7 exist. |
 |
|
Ifor
Aged Yak Warrior
700 Posts |
Posted - 2012-02-07 : 13:20:26
|
[code]WITH MerchandiseAS( SELECT ad.account, 'Merchandise' AS LOB, SUM(ac.volume1) as Volume_PYT, SUM(ac.volume2) as Volume_YTD, SUM(ac.volume3) as Volume_CY FROM accountdefinition ad LEFT JOIN SUMMARY ac ON ad.account = ac.account AND ad.lob = ac.lob WHERE ad.lob IN ('AG','CH','EM','FC','MT','PA','PF') GROUP BY ad.account HAVING COUNT(DISTINCT ad.lob) = 7)SELECT ad.account, ad.lob, SUM(ac.volume1) as Volume_PYT, SUM(ac.volume2) as Volume_YTD, SUM(ac.volume3) as Volume_CYFROM accountdefinition ad LEFT JOIN SUMMARY ac ON ad.account = ac.account AND ad.lob = ac.lobWHERE NOT EXISTS( SELECT * FROM Merchandise M WHERE ad.account = M.account AND ad.lob IN ('AG','CH','EM','FC','MT','PA','PF'))GROUP BY ad.account, ad.lobUNION ALLSELECT *FROM MerchandiseORDER BY account, lob;[/code] |
 |
|
jjw
Starting Member
9 Posts |
Posted - 2012-02-07 : 13:24:58
|
This query appears to identify the accounts that qualify for Merchandise groupingselect account,COUNT(distinct lob) from accountdefinition where lob in ('AG','CH','EM','FC','MT','PA','PF')group by accounthaving COUNT(distinct lob) = 7 |
 |
|
Ifor
Aged Yak Warrior
700 Posts |
Posted - 2012-02-07 : 13:28:47
|
This may perform better:WITH MerchandiseAS( SELECT account FROM accountdefinition WHERE lob IN ('AG','CH','EM','FC','MT','PA','PF') GROUP BY account HAVING COUNT(lob) = 7)SELECT ad.account, ad.lob, SUM(ac.volume1) as Volume_PYT, SUM(ac.volume2) as Volume_YTD, SUM(ac.volume3) as Volume_CYFROM accountdefinition ad LEFT JOIN SUMMARY ac ON ad.account = ac.account AND ad.lob = ac.lobWHERE NOT EXISTS( SELECT * FROM Merchandise M WHERE ad.account = M.account AND ad.lob IN ('AG','CH','EM','FC','MT','PA','PF'))GROUP BY ad.account, ad.lobUNION ALLSELECT ad.account, 'Merchandise' AS LOB, SUM(ac.volume1) as Volume_PYT, SUM(ac.volume2) as Volume_YTD, SUM(ac.volume3) as Volume_CYFROM accountdefinition ad LEFT JOIN SUMMARY ac ON ad.account = ac.account AND ad.lob = ac.lobWHERE EXISTS( SELECT * FROM Merchandise M WHERE ad.account = M.account AND ad.lob IN ('AG','CH','EM','FC','MT','PA','PF'))GROUP BY ad.accountORDER BY account, lob; |
 |
|
jjw
Starting Member
9 Posts |
Posted - 2012-02-07 : 13:31:17
|
Awesome!!!! Thank-You very much!!! quote: Originally posted by Ifor
WITH MerchandiseAS( SELECT ad.account, 'Merchandise' AS LOB, SUM(ac.volume1) as Volume_PYT, SUM(ac.volume2) as Volume_YTD, SUM(ac.volume3) as Volume_CY FROM accountdefinition ad LEFT JOIN SUMMARY ac ON ad.account = ac.account AND ad.lob = ac.lob WHERE ad.lob IN ('AG','CH','EM','FC','MT','PA','PF') GROUP BY ad.account HAVING COUNT(DISTINCT ad.lob) = 7)SELECT ad.account, ad.lob, SUM(ac.volume1) as Volume_PYT, SUM(ac.volume2) as Volume_YTD, SUM(ac.volume3) as Volume_CYFROM accountdefinition ad LEFT JOIN SUMMARY ac ON ad.account = ac.account AND ad.lob = ac.lobWHERE NOT EXISTS( SELECT * FROM Merchandise M WHERE ad.account = M.account AND ad.lob IN ('AG','CH','EM','FC','MT','PA','PF'))GROUP BY ad.account, ad.lobUNION ALLSELECT *FROM MerchandiseORDER BY account, lob;
|
 |
|
|
|
|