SQL 避免在子查询上使用多部分标识符
SQL avoiding Multipart Identifier on subquery
使用 SQLExpress 2017
我有一些产品分布在各个仓库,我想看看需要库存多少产品才能满足给定期间的销售。
Need pr. warehouse = Stock - CustomerOrders + SupplierOrders - SumOfSalesInPeriod
现在我想对每种产品进行总结,但我对已经满足需求的仓库不感兴趣,所以我只想要负值,但我很难像现在这样工作遇到多部分标识符错误。
使用 distinct 关键字也让我觉得我做的计算太多了,一定有更好的方法。
declare @fromDate date = '1900-01-01 12:00:00';
declare @toDate date = '3000-01-01 12:00:00';
select *,
balance =
(select
turn = sum(TurnOver)
from (
select
WarehouseStocks.Id,
TurnOver = WarehouseStocks.Qty
- WarehouseStocks.OrderedByCustomersQty
+ WarehouseStocks.OrderedFromSuppliersQty
- isnull((select Sum(StockEntries.Qty)
from StockEntries
where
StockEntries.Type = 1
and StockEntries.ProductId = WarehouseStocks.Id
and WarehouseStocks.WarehouseId = StockEntries.WarehouseId
and StockEntries.Date >= @fromDate
and StockEntries.Date <= @toDate), 0)
from WarehouseStocks) Product where TurnOver < 0
group by Product.Id) tp where Products.Id = tp.Id)
from Products
我会改用 CTE 重写它,将其分解并使查询更具可读性。像这样:
declare @fromDate date = '1900-01-01 12:00:00';
declare @toDate date = '3000-01-01 12:00:00';
;with SE
as
(
select Sum(StockEntries.Qty) as SumStockEnties , StockEntries.ProductId, StockEntries.WarehouseId
from StockEntries
where
StockEntries.Type = 1
and StockEntries.Date >= @fromDate
and StockEntries.Date <= @toDate
group by StockEntries.ProductId, StockEntries.WarehouseId
),
TP
as
(
Select WS.Id, WS.Qty - WS.OrderedByCustomersQty + WS.OrderedFromSuppliersQty - isnulle(SE.SumStockEnties, 0) as TurnOver
from WarehouseStocks as WS
left join SE
on SE.ProductId = WS.Id
and SE.WarehouseId = WS.WarehouseId
)
Select *
from TP
inner join Products as PR
on PR.id = TP.id
Where PR.TurnOver < 0
使用 SQLExpress 2017
我有一些产品分布在各个仓库,我想看看需要库存多少产品才能满足给定期间的销售。
Need pr. warehouse = Stock - CustomerOrders + SupplierOrders - SumOfSalesInPeriod
现在我想对每种产品进行总结,但我对已经满足需求的仓库不感兴趣,所以我只想要负值,但我很难像现在这样工作遇到多部分标识符错误。 使用 distinct 关键字也让我觉得我做的计算太多了,一定有更好的方法。
declare @fromDate date = '1900-01-01 12:00:00';
declare @toDate date = '3000-01-01 12:00:00';
select *,
balance =
(select
turn = sum(TurnOver)
from (
select
WarehouseStocks.Id,
TurnOver = WarehouseStocks.Qty
- WarehouseStocks.OrderedByCustomersQty
+ WarehouseStocks.OrderedFromSuppliersQty
- isnull((select Sum(StockEntries.Qty)
from StockEntries
where
StockEntries.Type = 1
and StockEntries.ProductId = WarehouseStocks.Id
and WarehouseStocks.WarehouseId = StockEntries.WarehouseId
and StockEntries.Date >= @fromDate
and StockEntries.Date <= @toDate), 0)
from WarehouseStocks) Product where TurnOver < 0
group by Product.Id) tp where Products.Id = tp.Id)
from Products
我会改用 CTE 重写它,将其分解并使查询更具可读性。像这样:
declare @fromDate date = '1900-01-01 12:00:00';
declare @toDate date = '3000-01-01 12:00:00';
;with SE
as
(
select Sum(StockEntries.Qty) as SumStockEnties , StockEntries.ProductId, StockEntries.WarehouseId
from StockEntries
where
StockEntries.Type = 1
and StockEntries.Date >= @fromDate
and StockEntries.Date <= @toDate
group by StockEntries.ProductId, StockEntries.WarehouseId
),
TP
as
(
Select WS.Id, WS.Qty - WS.OrderedByCustomersQty + WS.OrderedFromSuppliersQty - isnulle(SE.SumStockEnties, 0) as TurnOver
from WarehouseStocks as WS
left join SE
on SE.ProductId = WS.Id
and SE.WarehouseId = WS.WarehouseId
)
Select *
from TP
inner join Products as PR
on PR.id = TP.id
Where PR.TurnOver < 0