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 |
shanmugaraj
Posting Yak Master
219 Posts |
Posted - 2013-12-19 : 14:47:54
|
Product Id IsPrimary QuantityP001 1 P001.1 0 2P001.2 0 4P001.3 0 5P002 1 P002.1 0 6P002.2 0 7P002.3 0 9P002.4 0 10P002.5 0 11 Need the query for result each group shows multiplied value of group quantity and last row of the group is shown with NULL Product Id SubProduct QuantityP001 40P001 P001.3 NULLP002 41580P002 P002.5 NULLThis is same as http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=190438I am now looking for the logic to have the last posted senario ..Kindly suggestTHANKSSHANMUGARAJnshanmugaraj@gmail.com |
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2013-12-19 : 16:09:26
|
There are a couple awkward things about this request - and awkward usually indicates either a bad data model or an unusual presentation requirement. In this case both. There is a reason that sql server does not provide a PRODUCT aggregate function. It doesn't take much to blow out any data type range.But this example seems to work for your sample data - I can't imagine you really need or even want this:set nocount ondeclare @t table (ProductId varchar(25), Quantity int)insert @t select 'P001', 1 union allselect 'P001.1' ,2 union allselect 'P001.2' ,4 union allselect 'P001.3' ,5 union allselect 'P002', 1 union allselect 'P002.1' ,6 union allselect 'P002.2' ,7 union allselect 'P002.3' ,9 union allselect 'P002.4' ,10 union allselect 'P002.5' ,11set nocount off--sequence the rows so we can recurse through them;with t (prodRoot, productid, quantity, rn)as( select left(productID, 4), productID, Quantity, row_number() over (partition by left(productID, 4) order by productID) from @t)--perform the PRODUCT aggregations,t1 (prodRoot, productid, product, rn)as( select prodRoot, productID, Quantity, rn from t where rn = 1 union all select t.prodRoot, t.productID, t1.product * t.Quantity, t.rn from t join t1 on t1.prodRoot = t.prodRoot and t1.rn+1 = t.rn)--return the row with the final productselect prodRoot productID, null subProductID, max(product) quantityfrom t1 group by prodRootunion all--return the row of the last productIDselect prodRoot, productid, nullfrom (select seq = row_number() over (partition by prodRoot order by rn desc) ,productID ,prodRoot from t1) dwhere seq = 1--order it as you specifiedorder by 1, 3 descOUTPUT:productID subProductID quantity--------- ------------------------- -----------P001 NULL 40P001 P001.3 NULLP002 NULL 41580P002 P002.5 NULL Be One with the OptimizerTG |
 |
|
shanmugaraj
Posting Yak Master
219 Posts |
Posted - 2013-12-20 : 06:20:14
|
Thanks for the response. I will take your advice and will work accordinly for better performanceTHANKSSHANMUGARAJnshanmugaraj@gmail.com |
 |
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2013-12-20 : 10:57:33
|
one thing that would make things easier (in a relational db design) is if you had separate model for the product and Sub-Product hierarchy rather than having a single value that needs to be decoded to get the root.Another thing is your subject says "sum" (add the member values) but your example shows "product" (multiply the member values). Just want to confirm you really wanted product. And I'm curious why you need that.Be One with the OptimizerTG |
 |
|
waterduck
Aged Yak Warrior
982 Posts |
Posted - 2013-12-23 : 21:19:06
|
[code]declare @t table (ProductId varchar(25), isPrimary int, Quantity int)insert @t select 'P001', 1, 1 union allselect 'P001.1', 0, 2 union allselect 'P001.2', 0, 4 union allselect 'P001.3', 0, 5 union allselect 'P002', 1, 1 union allselect 'P002.1', 0,6 union allselect 'P002.2', 0,7 union allselect 'P002.3', 0,9 union allselect 'P002.4', 0,10 union allselect 'P002.5', 0,11set nocount off;WITH CTE AS( SELECT ParentID = ProductId , ProductId , Quantity , childrn = CASE WHEN ISNUMERIC(PARSENAME(ProductId, 1)) = 0 THEN 1 ELSE CAST(PARSENAME(ProductId, 1) AS INT) END FROM @t WHERE isPrimary = 1 UNION ALL SELECT ParentID = parent.ProductId , child.ProductId , child.Quantity * parent.Quantity , CASE WHEN ISNUMERIC(PARSENAME(child.ProductId, 1)) = 0 THEN 0 ELSE CAST(PARSENAME(child.ProductId, 1) AS INT) END + 1 FROM @t child JOIN CTE parent ON LEFT(child.ProductId, 4) = LEFT(parent.ProductId, 4) AND CASE WHEN ISNUMERIC(PARSENAME(child.ProductId, 1)) = 0 THEN 0 ELSE CAST(PARSENAME(child.ProductId, 1) AS INT) END = childrn )SELECT *FROM CTE aWHERE (childrn = 1) OR (ProductId = (SELECT MAX(ProductId) FROM CTE b WHERE LEFT(a.ProductId, 4) = LEFT(b.ProductId, 4)))ORDER BY 1[/code] |
 |
|
shanmugaraj
Posting Yak Master
219 Posts |
|
|
|
|
|
|