在SQL查询或视图中重用计算列

时间:2015-02-09 11:35:44

标签: sql-server tsql

我正在编写一些基本库存控制系统,需要计算一些数字来订购供应商的产品。

我想做的是这样的查询:

   SELECT [Articles].[ArticleId]
         ,(SELECT COALESCE(SUM([Quantity]),0) FROM [dbo].[InventoryTable] WHERE [InventoryTable].ArticleId = [Articles].[ArticleId]) AS 'QuantityInStorage'
         ,(SELECT COALESCE(SUM([Quantity]),0) FROM [dbo].[CustomerOrdersTable] WHERE [CustomerOrdersTable].ArticleId = [Articles].[ArticleId]) AS 'QuantityDeliverToCustomers'
         ,(SELECT COALESCE(SUM([Quantity]),0) FROM [dbo].[SupplierOrdersTable] WHERE [SupplierOrdersTable].ArticleId = [Articles].[ArticleId]) AS 'QuantityOrderedFromSupplier'
         ,[Reorderlevel]
         ,[RefillQuantityToLevel]
         ,CASE 
           WHEN [Reorderlevel] <> 0 THEN ([QuantityInStorage]+[QuantityOrderedFromSupplier]-[QuantityDeliverToCustomers])*100/[Reorderlevel] -- compute how important it is to restock on this item
           WHEN ([QuantityInStorage]+[QuantityOrderedFromSupplier]-[QuantityDeliverToCustomers]) < 0 THEN -1 -- we don't want the article in storage but need to order it to send it to customers
           ELSE 999 -- unimportant, don't order this stuff
          END  AS 'Importance' -- below zero is very important (need article to send to customer), below 100 is some kind important (refill storage), above 100 is not important
     FROM [Articles]
     WHERE [QuantityInStorage]-[QuantityDeliverToCustomers]+[QuantityOrderedFromSupplier]<[RefillQuantityToLevel]
     ORDER BY [Importance] 

我的问题是:如何在我的示例中尝试重新使用计算列?如果我尝试这个,SQL Server总是会显示错误。

3 个答案:

答案 0 :(得分:1)

将查询设为subselect,不能在同一个select语句中使用别名。

SELECT *,
       CASE
         WHEN [Reorderlevel] <> 0 THEN ( [QuantityInStorage]
                                         + [QuantityOrderedFromSupplier] - [QuantityDeliverToCustomers] ) * 100 / [Reorderlevel] -- compute how important it is to restock on this item
         WHEN ( [QuantityInStorage]
                + [QuantityOrderedFromSupplier] - [QuantityDeliverToCustomers] ) < 0 THEN -1 -- we don't want the article in storage but need to order it to send it to customers
         ELSE 999 -- unimportant, don't order this stuff
       END AS 'Importance' -- below zero is very important (need article to send to customer), below 100 is some kind important (refill storage), above 100 is not important
FROM   (SELECT [Articles].[ArticleId],
               (SELECT COALESCE(Sum([Quantity]), 0)
                FROM   [dbo].[InventoryTable]
                WHERE  [InventoryTable].ArticleId = [Articles].[ArticleId])      AS 'QuantityInStorage',
               (SELECT COALESCE(Sum([Quantity]), 0)
                FROM   [dbo].[CustomerOrdersTable]
                WHERE  [CustomerOrdersTable].ArticleId = [Articles].[ArticleId]) AS 'QuantityDeliverToCustomers',
               (SELECT COALESCE(Sum([Quantity]), 0)
                FROM   [dbo].[SupplierOrdersTable]
                WHERE  [SupplierOrdersTable].ArticleId = [Articles].[ArticleId]) AS 'QuantityOrderedFromSupplier',
               [Reorderlevel],
               [RefillQuantityToLevel],
               [Importance]
        FROM   [Articles]) a
WHERE  [QuantityInStorage] - [QuantityDeliverToCustomers] + [QuantityOrderedFromSupplier] < [RefillQuantityToLevel]
ORDER  BY [Importance] 

答案 1 :(得分:1)

使用外部申请:

SELECT [Articles].[ArticleId]
        ,x.[QuantityInStorage]
        ,y.[QuantityDeliverToCustomers]
        ,z.[QuantityOrderedFromSupplier]
        ,[Reorderlevel]
        ,[RefillQuantityToLevel]
        ,CASE 
        WHEN [Reorderlevel] <> 0 THEN ([QuantityInStorage]+[QuantityOrderedFromSupplier]-[QuantityDeliverToCustomers])*100/[Reorderlevel] -- compute how important it is to restock on this item
        WHEN ([QuantityInStorage]+[QuantityOrderedFromSupplier]-[QuantityDeliverToCustomers]) < 0 THEN -1 -- we don't want the article in storage but need to order it to send it to customers
        ELSE 999 -- unimportant, don't order this stuff
        END  AS [Importance] -- below zero is very important (need article to send to customer), below 100 is some kind important (refill storage), above 100 is not important
FROM [Articles]
OUTER APPLY
  (SELECT COALESCE(SUM([Quantity]),0) [QuantityInStorage] FROM [dbo].[InventoryTable] WHERE [InventoryTable].ArticleId = [Articles].[ArticleId]) x
OUTER APPLY
  (SELECT COALESCE(SUM([Quantity]),0) [QuantityDeliverToCustomers] FROM [dbo].[CustomerOrdersTable] WHERE [CustomerOrdersTable].ArticleId = [Articles].[ArticleId]) y
OUTER APPLY
  (SELECT COALESCE(SUM([Quantity]),0) [QuantityOrderedFromSupplier] FROM [dbo].[SupplierOrdersTable] WHERE [SupplierOrdersTable].ArticleId = [Articles].[ArticleId]) z
WHERE [QuantityInStorage]-[QuantityDeliverToCustomers]+[QuantityOrderedFromSupplier]<[RefillQuantityToLevel]
ORDER BY [Importance] 

答案 2 :(得分:1)

未经测试,但这样的事情应该这样做:

with QuantityInStorage as (
  SELECT [InventoryTable].ArticleId, COALESCE(SUM([Quantity]),0) as Quantity FROM [dbo].[InventoryTable] GROUP BY [InventoryTable].ArticleId
)
, QuantityDeliverToCustomers as (
  SELECT [CustomerOrdersTable].ArticleId, COALESCE(SUM([Quantity]),0) as Quantity FROM [dbo].[CustomerOrdersTable] GROUP BY [CustomerOrdersTable].ArticleId 
)
,QuantityOrderedFromSupplier as (
  SELECT [SupplierOrdersTable].ArticleId, COALESCE(SUM([Quantity]),0)  AS Quantity FROM [dbo].[SupplierOrdersTable] GROUP BY [SupplierOrdersTable].ArticleId
)
SELECT [Articles].[ArticleId]
         , QuantityInStorage.Quantity as QuantityInStorage
         , QuantityDeliverToCustomers.Quantity AS QuantityDeliverToCustomers
         , QuantityOrderedFromSupplier.Quantity as QuantityOrderedFromSupplier
         ,[Reorderlevel]
         ,[RefillQuantityToLevel]
         ,CASE 
           WHEN [Reorderlevel] <> 0 THEN (QuantityInStorage.Quantity + QuantityOrderedFromSupplier.Quantity-QuantityDeliverToCustomers.Quantity)*100/[Reorderlevel] -- compute how important it is to restock on this item
           WHEN (QuantityInStorage.Quantity+ QuantityOrderedFromSupplier.Quantity-QuantityDeliverToCustomers.Quantity) < 0 THEN -1 -- we don't want the article in storage but need to order it to send it to customers
           ELSE 999 -- unimportant, don't order this stuff
          END  AS 'Importance' -- below zero is very important (need article to send to customer), below 100 is some kind important (refill storage), above 100 is not important

 FROM [Articles]
LEFT OUTER JOIN QuantityInStorage ON QuantityInStorage.ArticleId=[Articles].ArticleId
LEFT OUTER JOIN QuantityDeliverToCustomers ON QuantityDeliverToCustomers.ArticleId=[Articles].ArticleId
LEFT OUTER JOIN QuantityOrderedFromSupplier ON QuantityOrderedFromSupplier.ArticleId=[Articles].ArticleId
WHERE [QuantityInStorage].Quantity-[QuantityDeliverToCustomers].Quantity+[QuantityOrderedFromSupplier].Quantity<[RefillQuantityToLevel]