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.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Multiply of columns based on new group

Author  Topic 

shanmugaraj
Posting Yak Master

219 Posts

Posted - 2013-12-19 : 14:47:54
Product Id IsPrimary Quantity
P001 1
P001.1 0 2
P001.2 0 4
P001.3 0 5
P002 1
P002.1 0 6
P002.2 0 7
P002.3 0 9
P002.4 0 10
P002.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 Quantity
P001 40
P001 P001.3 NULL
P002 41580
P002 P002.5 NULL

This is same as
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=190438
I am now looking for the logic to have the last posted senario ..
Kindly suggest

THANKS
SHANMUGARAJ
nshanmugaraj@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 on
declare @t table (ProductId varchar(25), Quantity int)
insert @t
select 'P001', 1 union all
select 'P001.1' ,2 union all
select 'P001.2' ,4 union all
select 'P001.3' ,5 union all
select 'P002', 1 union all
select 'P002.1' ,6 union all
select 'P002.2' ,7 union all
select 'P002.3' ,9 union all
select 'P002.4' ,10 union all
select 'P002.5' ,11
set 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 product
select prodRoot productID, null subProductID, max(product) quantity
from t1
group by prodRoot

union all

--return the row of the last productID
select prodRoot, productid, null
from (select seq = row_number() over (partition by prodRoot order by rn desc)
,productID
,prodRoot
from t1) d
where seq = 1

--order it as you specified
order by 1, 3 desc

OUTPUT:

productID subProductID quantity
--------- ------------------------- -----------
P001 NULL 40
P001 P001.3 NULL
P002 NULL 41580
P002 P002.5 NULL




Be One with the Optimizer
TG
Go to Top of Page

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 performance

THANKS
SHANMUGARAJ
nshanmugaraj@gmail.com
Go to Top of Page

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 Optimizer
TG
Go to Top of Page

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 all
select 'P001.1', 0, 2 union all
select 'P001.2', 0, 4 union all
select 'P001.3', 0, 5 union all
select 'P002', 1, 1 union all
select 'P002.1', 0,6 union all
select 'P002.2', 0,7 union all
select 'P002.3', 0,9 union all
select 'P002.4', 0,10 union all
select 'P002.5', 0,11
set 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 a
WHERE (childrn = 1) OR (ProductId = (SELECT MAX(ProductId) FROM CTE b WHERE LEFT(a.ProductId, 4) = LEFT(b.ProductId, 4)))
ORDER BY 1
[/code]
Go to Top of Page

shanmugaraj
Posting Yak Master

219 Posts

Posted - 2013-12-24 : 06:13:33
This is fine.. could you help me on the realtime scenario as

This is same as
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=190438 .
Kindly suggest

THANKS
SHANMUGARAJ
nshanmugaraj@gmail.com
Go to Top of Page
   

- Advertisement -