I have a query which has 5 subqueries. I need it to have only 4 subqueries, since two of them are supposed to be only one result. The problem is I don’t know how to maintain the query structure and get the MIN value of 2 of those subqueries. This is my query:
x
Select Artigo, Descricao, sum(Stock) as Stock, Sum(QuantidadeEmEncomendasPendentes) as QuantidadeEmEncomendasPendentes, Sum(Stock) - Sum(QuantidadeEmEncomendasPendentes) As StockTotal
From (
Select A1.Artigo as Artigo, A1.Descricao as Descricao, sum(AA.StkActual) as Stock, 0 as QuantidadeEmEncomendasPendentes, 'Artigo Stock' As Id
From Artigo A1
Inner Join ArtigoArmazem AA On AA.Artigo = A1.Artigo And (AA.Armazem IN ('A1','A5','A7','A8','A9'))
and A1.CDU_DisponivelOnline = 1
Group By A1.Artigo, A1.Descricao
Union
Select A1.Artigo as Artigo, A1.Descricao as Descricao, 0 as Stock, Sum(LD.Quantidade - LDS.QuantTrans) as QuantidadeEmEncomendasPendentes, 'Artigo Encomenda' As Id
From Artigo A1
Inner Join LinhasDoc LD On LD.Artigo = A1.Artigo And Year(LD.Data) >= 2018 And LD.Quantidade Is Not Null And LD.Quantidade > 0
Inner Join LinhasDocStatus LDS On LDS.IdLinhasDoc = LD.Id And LDS.Fechado = 0 And LDS.Quantidade > LDS.QuantTrans
Inner Join CabecDocStatus CDS On CDS.IdCabecDoc = LD.IdCabecDoc And CDS.Fechado = 0 And CDS.Estado = 'P'
Inner Join CabecDoc CD On CD.Id = LD.IdCabecDoc And CD.TipoDoc = 'NET' And CD.Serie = 'SITE'
and A1.CDU_DisponivelOnline = 1
Group By A1.Artigo, A1.Descricao
Union
select
A1.Artigo as Artigo, A1.Descricao as Descricao, FLOOR(MIN(CASE WHEN A2.familia = 39 THEN AA.StkActual / 2 ELSE AA.StkActual END)) as Stock, 0 as QuantidadeEmEncomendasPendentes, 'Componente Stock' As Id
from
Artigo A1
join ComponentesArtigos CA On CA.ArtigoComposto = A1.Artigo
join Artigo A2 On A2.Artigo = CA.Componente And (A2.Familia IN (37,38,39,45))
join ArtigoArmazem AA ON AA.Artigo = A2.Artigo And (AA.Armazem IN ('A7'))
and A1.CDU_DisponivelOnline = 1
group by
A1.Artigo,
A1.Descricao
Union
select
A1.Artigo as Artigo, A1.Descricao as Descricao, (coalesce(MIN(
CASE
when AA.Armazem = 'A7' then
CASE WHEN A2.Familia = 98 THEN AA.StkActual END
else
null
end
), MIN(
CASE
when AA.Armazem = 'A8' then
CASE WHEN A2.Familia = 98 THEN AA.StkActual END
else
null
end
), MIN(
CASE
when AA.Armazem = 'A9' then
CASE WHEN A2.Familia = 98 THEN AA.StkActual END
else
null
end
))) as Stock, 0 as QuantidadeEmEncomendasPendentes, 'Componente Stock' As Id
from
Artigo A1
join ComponentesArtigos CA On CA.ArtigoComposto = A1.Artigo
join Artigo A2 On A2.Artigo = CA.Componente And (A2.Familia IN (98))
join ArtigoArmazem AA ON AA.Artigo = A2.Artigo And (AA.Armazem IN ('A7', 'A8', 'A9'))
and A1.CDU_DisponivelOnline = 1
group by
A1.Artigo,
A1.Descricao
Union
Select A1.Artigo as Artigo, A1.Descricao as Descricao, 0 as Stock, Sum(LD.Quantidade - LDS.QuantTrans) as QuantidadeEmEncomendasPendentes, 'Componente Encomenda' As Id
From Artigo A1
Inner Join ComponentesArtigos CA On CA.ArtigoComposto = A1.Artigo
Inner Join Artigo A2 On A2.Artigo = CA.Componente And (A2.Familia IN (37,38,39,45,98))
Inner Join LinhasDoc LD On LD.Artigo = A2.Artigo And Year(LD.Data) >= 2018 And LD.Quantidade Is Not Null And LD.Quantidade > 0
Inner Join LinhasDocStatus LDS On LDS.IdLinhasDoc = LD.Id And LDS.Fechado = 0 And LDS.Quantidade > LDS.QuantTrans
Inner Join CabecDocStatus CDS On CDS.IdCabecDoc = LD.IdCabecDoc And CDS.Fechado = 0 And CDS.Estado = 'P' And LDS.IdLinhasDoc Is Not Null
Inner Join CabecDoc CD On CD.Id = LD.IdCabecDoc And CD.TipoDoc = 'NET' And CD.Serie = 'SITE' And CDS.IdCabecDoc Is Not Null
and A1.CDU_DisponivelOnline = 1
Group By A1.Artigo, A1.Descricao
) As Result
Group by Artigo, Descricao
order by Descricao
And I need to get the minimum value of the 3rd and 4th subqueries instead of adding both of them to the SUM(Stock) of the main query. How can I achieve that? I need to maintain the query structure.. I need the MIN from the Result of those queries (3rd and 4th):
select
A1.Artigo as Artigo, A1.Descricao as Descricao, FLOOR(MIN(CASE WHEN A2.familia = 39 THEN AA.StkActual / 2 ELSE AA.StkActual END)) as Stock, 0 as QuantidadeEmEncomendasPendentes, 'Componente Stock' As Id
from
Artigo A1
join ComponentesArtigos CA On CA.ArtigoComposto = A1.Artigo
join Artigo A2 On A2.Artigo = CA.Componente And (A2.Familia IN (37,38,39,45))
join ArtigoArmazem AA ON AA.Artigo = A2.Artigo And (AA.Armazem IN ('A7'))
and A1.CDU_DisponivelOnline = 1
group by
A1.Artigo,
A1.Descricao
Union
select
A1.Artigo as Artigo, A1.Descricao as Descricao, (coalesce(MIN(
CASE
when AA.Armazem = 'A7' then
CASE WHEN A2.Familia = 98 THEN AA.StkActual END
else
null
end
), MIN(
CASE
when AA.Armazem = 'A8' then
CASE WHEN A2.Familia = 98 THEN AA.StkActual END
else
null
end
), MIN(
CASE
when AA.Armazem = 'A9' then
CASE WHEN A2.Familia = 98 THEN AA.StkActual END
else
null
end
))) as Stock, 0 as QuantidadeEmEncomendasPendentes, 'Componente Stock' As Id
from
Artigo A1
join ComponentesArtigos CA On CA.ArtigoComposto = A1.Artigo
join Artigo A2 On A2.Artigo = CA.Componente And (A2.Familia IN (98))
join ArtigoArmazem AA ON AA.Artigo = A2.Artigo And (AA.Armazem IN ('A7', 'A8', 'A9'))
and A1.CDU_DisponivelOnline = 1
group by
A1.Artigo,
A1.Descricao
Advertisement
Answer
Consider turning subqueries into multiple CTEs, then in UNION
query add columns for Stock3 and Stock4 based on corresponding Stock to aggregate for MIN
values, filling in NULL
s for other queries:
WITH first_agg AS (
SELECT A1.Artigo AS Artigo, A1.Descricao AS Descricao,
SUM(AA.StkActual) AS Stock,
0 AS QuantidadeEmEncomendasPendentes,
'Artigo Stock' AS Id
FROM Artigo A1
INNER JOIN ArtigoArmazem AA
ON AA.Artigo = A1.Artigo
AND (AA.Armazem IN ('A1','A5','A7','A8','A9'))
AND A1.CDU_DisponivelOnline = 1
GROUP BY A1.Artigo, A1.Descricao
),
second_agg AS (
SELECT A1.Artigo AS Artigo, A1.Descricao AS Descricao,
0 AS Stock,
SUM(LD.Quantidade - LDS.QuantTrans) AS QuantidadeEmEncomendasPendentes,
'Artigo Encomenda' AS Id
FROM Artigo A1
INNER JOIN LinhasDoc LD
ON LD.Artigo = A1.Artigo AND Year(LD.Data) >= 2018
AND LD.Quantidade Is Not Null AND LD.Quantidade > 0
INNER JOIN LinhasDocStatus LDS
ON LDS.IdLinhasDoc = LD.Id
AND LDS.Fechado = 0 AND LDS.Quantidade > LDS.QuantTrans
INNER JOIN CabecDocStatus CDS
ON CDS.IdCabecDoc = LD.IdCabecDoc
AND CDS.Fechado = 0 AND CDS.Estado = 'P'
INNER JOIN CabecDoc CD
ON CD.Id = LD.IdCabecDoc
AND CD.TipoDoc = 'NET' AND CD.Serie = 'SITE'
AND A1.CDU_DisponivelOnline = 1
GROUP BY A1.Artigo, A1.Descricao
),
third_agg AS (
SELECT
A1.Artigo AS Artigo, A1.Descricao AS Descricao,
FLOOR(MIN(CASE
WHEN A2.familia = 39
THEN AA.StkActual / 2
ELSE AA.StkActual
END)) AS Stock,
0 AS QuantidadeEmEncomendasPendentes,
'Componente Stock' AS Id
FROM
Artigo A1
INNER JOIN ComponentesArtigos CA
ON CA.ArtigoComposto = A1.Artigo
INNER JOIN Artigo A2
ON A2.Artigo = CA.Componente AND (A2.Familia IN (37,38,39,45))
INNER JOIN ArtigoArmazem AA
ON AA.Artigo = A2.Artigo AND (AA.Armazem IN ('A7'))
AND A1.CDU_DisponivelOnline = 1
GROUP BY
A1.Artigo,
A1.Descricao
),
fourth_agg AS (
SELECT A1.Artigo AS Artigo, A1.Descricao AS Descricao,
(COALESCE(MIN(
CASE
WHEN AA.Armazem = 'A7'
THEN CASE WHEN A2.Familia = 98 THEN AA.StkActual END
ELSE NULL
END
), MIN(
CASE
WHEN AA.Armazem = 'A8'
THEN CASE WHEN A2.Familia = 98 THEN AA.StkActual END
ELSE NULL
END
), MIN(
CASE
WHEN AA.Armazem = 'A9'
THEN CASE WHEN A2.Familia = 98 THEN AA.StkActual END
ELSE NULL
END
))) AS Stock,
0 AS QuantidadeEmEncomendasPendentes,
'Componente Stock' AS Id
FROM
Artigo A1
INNER JOIN ComponentesArtigos CA
ON CA.ArtigoComposto = A1.Artigo
INNER JOIN Artigo A2
ON A2.Artigo = CA.Componente AND (A2.Familia IN (98))
INNER JOIN ArtigoArmazem AA
ON AA.Artigo = A2.Artigo AND (AA.Armazem IN ('A7', 'A8', 'A9'))
AND A1.CDU_DisponivelOnline = 1
GROUP BY
A1.Artigo,
A1.Descricao
),
fifth_agg AS (
SELECT A1.Artigo AS Artigo, A1.Descricao AS Descricao,
0 AS Stock,
SUM(LD.Quantidade - LDS.QuantTrans) AS QuantidadeEmEncomendasPendentes,
'Componente Encomenda' AS Id
FROM Artigo A1
INNER JOIN ComponentesArtigos CA
ON CA.ArtigoComposto = A1.Artigo
INNER JOIN Artigo A2
ON A2.Artigo = CA.Componente AND (A2.Familia IN (37,38,39,45,98))
INNER JOIN LinhasDoc LD
ON LD.Artigo = A2.Artigo AND Year(LD.Data) >= 2018
AND LD.Quantidade Is Not Null AND LD.Quantidade > 0
INNER JOIN LinhasDocStatus LDS
ON LDS.IdLinhasDoc = LD.Id
AND LDS.Fechado = 0 AND LDS.Quantidade > LDS.QuantTrans
INNER JOIN CabecDocStatus CDS
ON CDS.IdCabecDoc = LD.IdCabecDoc AND CDS.Fechado = 0
AND CDS.Estado = 'P' AND LDS.IdLinhasDoc Is Not Null
INNER JOIN CabecDoc CD
ON CD.Id = LD.IdCabecDoc AND CD.TipoDoc = 'NET'
AND CD.Serie = 'SITE' AND CDS.IdCabecDoc Is Not Null
AND A1.CDU_DisponivelOnline = 1
GROUP BY A1.Artigo, A1.Descricao
)
SELECT Artigo, Descricao,
SUM(Stock) AS Stock,
SUM(QuantidadeEmEncomendasPendentes) AS QuantidadeEmEncomendasPendentes,
SUM(Stock) - SUM(QuantidadeEmEncomendasPendentes) AS StockTotal,
MIN(Stock3) AS MIN_Stock3,
MIN(Stock4) AS Min_Stock4
FROM (
SELECT Artigo, Descricao, Stock, NULL AS Stock3, NULL AS Stock4,
QuantidadeEmEncomendasPendentes, ID
FROM first_agg
UNION
SELECT Artigo, Descricao, Stock, NULL AS Stock3, NULL AS Stock4,
QuantidadeEmEncomendasPendentes, ID
FROM second_agg
UNION
SELECT Artigo, Descricao, Stock, Stock AS Stock3, NULL AS Stock4,
QuantidadeEmEncomendasPendentes, ID
FROM third_agg
UNION
SELECT Artigo, Descricao, Stock, NULL AS Stock3, Stock AS Stock4,
QuantidadeEmEncomendasPendentes, ID
FROM fourth_agg
UNION
SELECT Artigo, Descricao, Stock, NULL AS Stock3, NULL AS Stock4,
QuantidadeEmEncomendasPendentes, ID
FROM fifth_agg
) AS Result
GROUP BY Artigo, Descricao
ORDER BY Descricao