Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
178 views
in Technique[技术] by (71.8m points)

sql server - Aggregate with subselect or subquery

I'm trying to make a query that returns how much I can produce based on the lowest value of a sum of component units from different warehouses.

Data come from tables like these:

e.table
-------
codartp    codartc      unicompo
REF1       BLISTER1       1
REF1       BOX1           1
REF1       CHARGER1       2
REF2       BLISTER2       1
REF2       BOX2           1

s.table
------
codart      unidades      codalm
BLISTER1      100           4 
BLISTER1      150           1
BOX1          100           1
BOX1          100           4
BOX1          200           2
CHARGER1      50            3
CHARGER1      50            4 
BLISTER2      500           1
BLISTER2      300           4 
BOX2          150           2

I would need to sum how much I have from every component (blister, box, charger...) in total: BLISTER1: 250 BOX1: 400 CHARGER1: 100

And then return the lowest value divided by the unicompo (the ammount of components I need). With my stock of components, I could only produce 50 units of REF1: 100/2

Here is my subselect:

(select min(val) from (select sum(s1.unidades/e.unicompo) as val 
    from __STOCKALMART s1
    left join escandallo e on e.codartc = s1.codart
    where s1.codalm not in (0,9999) and e.codartp = l.codart) t) as PRODUCIBLE

The expected result would be something like this:

l.codart  producible
REF1          50
REF2          150

But I only managed to call either the min (in some warehouses is 0) or the sum of components, not min after the sum. I don't know if I'm explaining myself. Ask if I need to clarify anything

Thanks for your help

question from:https://stackoverflow.com/questions/65936555/aggregate-with-subselect-or-subquery

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As long as there is no overlap between your product compositions (so no two products share a common component, otherwise you are looking at something way more complex), then the query below should give you a solution.

Sample data

create table ProductComponent
(
  codartp nvarchar(4),  -- product
  codartc nvarchar(10), -- component
  unicompo int          -- amount
);

insert into ProductComponent (codartp, codartc, unicompo) values
('REF1', 'BLISTER1', 1),
('REF1', 'BOX1'    , 1),
('REF1', 'CHARGER1', 2),
('REF2', 'BLISTER2', 1),
('REF2', 'BOX2'    , 1);

create table ComponentInventory
(
  codart nvarchar(10), -- component
  unidades int,        -- amount
  codalm int           -- warehouse
);

insert into ComponentInventory (codart, unidades, codalm) values
('BLISTER1', 100, 4), 
('BLISTER1', 150, 1),
('BOX1'    , 100, 1),
('BOX1'    , 100, 4),
('BOX1'    , 200, 2),
('CHARGER1', 50 , 3),
('CHARGER1', 50 , 4), 
('BLISTER2', 500, 1),
('BLISTER2', 300, 4), 
('BOX2'    , 150, 2);

Solution

Using some common table expressions (CTE's) to:

  1. Sum up all the inventory components across the warehouses.
  2. Divide the previous sums according to the product composition.

This gives:

with cti as -- component inventory total
(
  select ci.codart,
         sum(ci.unidades) as unidades
  from ComponentInventory ci
  group by ci.codart
),
pci as -- product component inventory
(
  select pc.codartp,
         cti.unidades / pc.unicompo as maxPart
  from ProductComponent pc
  join cti
    on cti.codart = pc.codartc
)
select pci.codartp,
       min(pci.maxPart) as producibleAmount
from pci
group by pci.codartp
order by pci.codartp;

Result

codartp producibleAmount
------- ----------------
REF1    50
REF2    150

Fiddle to see it in action with intermediate CTE results.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...