I have the following (summarized) sales invoice table from a customer ERP's SQL database. I've filtered out a single invoice for this example.
LINTYP_0 | LINTYP_DESC | InvoiceNumber | ItemCode | Cost |
---|---|---|---|---|
2 | Fixed Kit | DIR000028 | FIN051 | 0.00 |
3 | Fixed Kit Component | DIR000028 | BMS003 | 1000.00 |
3 | Fixed Kit Component | DIR000028 | BMS059 | 1000.00 |
6 | Flex Kit | DIR000028 | FIN009 | 0.00 |
7 | Flex Kit Component | DIR000028 | FIN010 | 1000.00 |
7 | Flex Kit Component | DIR000028 | BMS057 | 1000.00 |
7 | Flex Kit Component | DIR000028 | BTB001 | 1000.00 |
7 | Flex Kit Component | DIR000028 | DIS001 | 1000.00 |
7 | Flex Kit Component | DIR000028 | DIS003 | 1000.00 |
8 | Flex Kit Component | DIR000028 | DIS010 | 1000.00 |
1 | Normal | DIR000028 | BMS057 | 1000.00 |
... | ... | ... | ... | ... |
In this table, "Fixed" and "Flex" kits are discrete bundles of items (lintyp 2 and 6 respectively), and components are of course the component items within those kits. My problem is that, as you can see above, my costs per kit are always 0 as the ERP does not natively sum up and store costs. The challenge is that the SQL tables also do not contain any sort of parent-child relationship between kits and components.
My desired output would be to have only kit-type item codes with the sum of their components' costs, as well as any "normal" type items left as-is. Visually, it would look like the following...
LINTYP_0 | LINTYP_DESC | InvoiceNumber | ItemCode | Cost |
---|---|---|---|---|
2 | Fixed Kit | DIR000028 | FIN051 | 2000.00 |
6 | Flex Kit | DIR000028 | FIN009 | 6000.00 |
1 | Normal | DIR000028 | BMS057 | 1000.00 |
I imagine I would need a cursor to iterate through the table, or some sort of usage of the LEAD/LAG window function, however I'm having a difficult time fleshing out the logic.
It is worth noting that the ERP always organizes items within an invoice such that, if there is a kit, the corresponding component items will follow, so use of the LEAD/LAG function is a reliable option. (edit: lets assume I have a field that ensures the order is reliable)
How can I accomplish this output?
CodePudding user response:
Can you try
DECLARE @T TABLE (
LINTYP_DESC VARCHAR(100)
,Cost INT
,ItemCode VARCHAR(10)
)
INSERT INTO @T
VALUES('Fixed Kit',1000,'FIN051')
,('Fixed Kit Component',1000,'BMS003')
,('Normal',1000,'BMS057')
,('Flex Kit',1000,'FIN009')
,('Flex Kit Component',1000,'FIN010')
SELECT T.LINTYP_DESC,T.ItemCode,
C.TOTAL FROM @T T
LEFT JOIN (
SELECT REPLACE(LINTYP_DESC,'Component','')LINTYP_DESC, SUM(Cost)TOTAL FROM @T
GROUP BY REPLACE(LINTYP_DESC,'Component',''))C ON C.LINTYP_DESC = T.LINTYP_DESC
WHERE C.LINTYP_DESC IS NOT NULL
CodePudding user response:
select min(LINTYP_0) as LINTYP_0
,min(LINTYP_DESC) as LINTYP_DESC
,min(InvoiceNumber) as InvoiceNumber
,min(case when LINTYP_DESC not like('%Component%') then ItemCode end) as ItemCode
,sum(Cost) as cost
from (
select *
,case when LINTYP_DESC like('%Fixed Kit%') then 1
when LINTYP_DESC like('%Flex Kit%') then 2
else 3 end as grp
from t
) t
group by grp
LINTYP_0 | LINTYP_DESC | InvoiceNumber | ItemCode | cost |
---|---|---|---|---|
2 | Fixed Kit | DIR000028 | FIN051 | 2000 |
6 | Flex Kit | DIR000028 | FIN009 | 6000 |
1 | Normal | DIR000028 | BMS057 | 1000 |