我有两个桌子。 SalesData和AllOffers。
SalesData表具有品牌(不能为空),产品类型(不能为空),批次(不能为空),产品尺寸(不能为空),舞台(不能为空),省份(如果Stage =“ WIP”),包装日期(永远不能为null)和数量(永远不能为null),则为null。
AllOffers表具有Province(永远不能为空),要约编号(永远不能为空),产品类型(可以为空),品牌(永远不能为空),产品尺寸(永远不能为空),手数(永远不能为空),日期包装(永远不能为空),数量(永远不能为空)和商品状态(永远不能为空)。
我有一个包含两个窗格的应用程序。用户在左侧窗格中基于SalesData中可用的手创建“要约”,而右侧窗格显示具有附加“可用数量”列的SalesData表,该列是在用户创建要约时即时计算的。
数据需要按省,阶段,产品类型,尺寸和装箱日期进行分组,以提供可用数量。由于省份和产品类型为空,我无法对数据进行分组。
这就是我所拥有的
SELECT
SalesData.Province,
SalesData.Stage,
SalesData.ProdType,
SalesData.Brand,
SalesData.Size,
SalesData.Lot,
SalesData.PackedOn,
SalesData.Qty,
CAST(SalesData.Qty AS decimal(12, 0)) - CAST(AllOffersSub.Qty AS decimal(12, 0)) AS Available
FROM
SalesData LEFT OUTER JOIN
(
SELECT
Province,
Brand,
Stage,
Lot,
Size,
PackedOn,
ProdType,
SUM(CAST(Quantity AS decimal(12, 0))) AS Qty
FROM
AllOffers
WHERE
(OfferStatus = 'Unconfirmed')
OR (OfferStatus = 'Confirmed')
GROUP BY
Province,
Brand,
Stage,
Lot,
Size,
PackedOn,
ProdType
) AS AllOffersSub ON
AllOffersSub.Brand = SalesData.Brand
AND AllOffersSub.Lot = SalesData.Lot
AND AllOffersSub.Size = SalesData.Size
AND AllOffersSub.PackedOn = SalesData.PackedOn
AND AllOffersSub.Stage= SalesData.Stage
AND CASE
WHEN SalesData.Province IS NULL THEN 1
WHEN AllOfferssub.Province = SalesData.Province THEN 1
ELSE 0 END =1
AND CASE
WHEN SalesData.ProdType IS NULL AND AllOffersSub.ProdType IS NULL THEN 1
WHEN AllOfferssub.ProdType = SalesData.ProdType THEN 1
ELSE 0
END = 1;
问题在于,很多项目可以显示为WIP(进行中的工作,这意味着省份为空)和FG(制成品,这意味着省份不会为空)。对于这么多的订单,就不会进行分组,最后我得到了一个批次,并在日期,阶段,产品类型,尺寸上打包了相同的包装,显示的次数是与该批次有关的订单数的两倍。
有没有一种方法可以根据条件有选择地分组?例如,如果stage =“ WIP”,则按阶段,产品类型,尺寸和包装日期分组,否则按阶段,产品类型,尺寸和包装日期分组?
这是“优惠”表的示例:
ID|Customer|OfferNum|Stage|ProdType|Brand|Size|Lot|PackedOn|Quantity|Status
1 |A | A1 |WIP | Null |test |Tst |aaa|1/1/2020|100 |Confirmed
2 |B | B1 |WIP | Null |test |Tst |aaa|1/1/2020|100 |Unconfirmed
3 |C | C1 |WIP | Null |test |Tst |aaa|1/1/2020|100 |Unconfirmed
4 |C | C1 |FG | Null |test |Tst |aaa|1/1/2020|100 |Unconfirmed
这是SalesData表的示例:
ID|Brand|ProdType|Lot|Size|Stage|Customer|PackedOn|Qty
1 |test | Null |aaa|Tst |WIP |Null |1/1/2020|1000
2 |test | Null |aaa|Tst |FG |C |1/1/2020|1000
查询结果为:
Customer|Stage|ProdType|Brand|Size|Lot|PackedOn|Qty |Available
Null |WIP | Null |test |Tst |aaa|1/1/2020|1000|900
Null |WIP | Null |test |Tst |aaa|1/1/2020|1000|900
Null |WIP | Null |test |Tst |aaa|1/1/2020|1000|900
C |FG | Null |test |Tst |aaa|1/1/2020|1000|900
结果应为:
Customer|Stage|ProdType|Brand|Size|Lot|PackedOn|Qty |Available
Null |WIP | Null |test |Tst |aaa|1/1/2020|1000|700
C |FG | Null |test |Tst |aaa|1/1/2020|1000|900
答案 0 :(得分:1)
我对您的查询进行了一些更改,但关键是您需要将子查询中的province
更改为
iif(stage = 'wip', null, province)
为避免在select语句和group子句中重复代码,我将其放入名为ap
的交叉应用语句中并从中选择。
除此之外,我只是将您的子查询放入公共表表达式中,将on
子句中的case语句转换为or
语句,然后重新设置样式。
with modifiedOffers as (
select ap.Province,
Brand, Stage, Lot, Size, PackedOn, ProdType,
Qty = sum(cast(Quantity as decimal(12, 0)))
from @allOffers o
cross apply (select Province = iif(stage = 'wip', null, province)) ap
where o.Status in ('Unconfirmed', 'Confirmed')
group by ap.Province, Brand, Stage, Lot, Size, PackedOn, ProdType
)
select sd.Province, sd.Stage, sd.ProdType, sd.Brand, sd.Size, sd.Lot, sd.PackedOn, sd.Qty,
Available = CAST(sd.Qty AS decimal(12, 0)) - o.Qty
from @salesData sd
left join modifiedOffers o
on o.Brand = sd.Brand
and o.Lot = sd.Lot
and o.Size = sd.Size
and o.PackedOn = sd.PackedOn
and o.Stage = sd.Stage
and (o.Province = sd.Province or sd.Province is null)
and (o.ProdType = sd.ProdType or sd.ProdType is null and o.ProdType is null);