如果select语句中包含外部条件,则减少同一子查询的多次重复。

问题描述 投票:1回答:3

我有一个表,其中包含物品的交易信息,可能的交易是购买(type_id: 1)和销售(type_id: 2)。可能的交易是购买(type_id: 1)和销售(type_id: 2)。表 "Transactions "的一个真正的简化版本如下。

Transaction_ID  Item_ID  Transaction_Type_ID  Quantity  Price  Date
1,               1,        1,                    50,        10,     6/1,
2,               2,        1,                    40,        20,     13/1,
3,               1,        2,                    10,        13,     14/1,
4,               2,        2,                    20,        25,     3/2,
5,               1,        2,                    20,        12,     20/2

我有如下查询:

SELECT B.Item_ID
       B.Quantity - (SELECT SUM(Quantity) FROM Transactions A Where A.Item_ID = B.Item_ID AND A.Transaction_Type_ID = 2) AS 'Quantity Left'
       B.Price * (B.Quantity - (SELECT SUM(Quantity) FROM Transactions A Where A.Item_ID = B.Item_ID AND A.Transaction_Type_ID = 2)) AS 'Purchase Amount Left'
FROM   Transaction B
WHERE  B.Transaction_Type_ID = 1
AND    B.Quantity - (SELECT SUM(Quantity) FROM Transactions A Where A.Item_ID = B.Item_ID AND A.Transaction_Type_ID = 2) > 0

就像你可能已经注意到的那样,我试图得到所有购买的物品,这些物品仍然有库存。你可能会注意到,在 "交易 "表中有一个恼人的子查询重复了两次。SELECT 句,一旦在 WHERE 条款。

如何减少?是否可以使用 WITH 在这种情况下,在语句的开头?

tsql sql-server-2008-r2
3个回答
2
投票

JOIN到一个聚合派生表上?

SELECT 
    B.Item_ID
    B.Quantity - ISNULL(A.SUMQuantity, 0) AS 'Quantity Left',
    B.Price * (B.Quantity - ISNULL(A.SUMQuantity, 0)) AS 'Purchase Amount Left'
FROM  
    Transaction B
    LEFT JOIN
    (
     SELECT SUM(Quantity) AS SUMQuantity, Item_ID
     FROM Transaction 
     WHERE Transaction_Type_ID = 2
     GROUP BY Item_ID
    ) ON A.Item_ID = B.Item_ID
WHERE  
    B.Transaction_Type_ID = 1
    AND   
    B.Quantity - ISNULL(A.SUMQuantity, 0) > 0

如果你总是有Transaction_Type_ID=2的行,那么你可以删除LEFT JOIN和ISNULL。在你当前的代码中,你假设你总是有行。

它看起来也像你根据Transaction_Type_ID在同一个表中混合实体。一个简单的 SUM(Quantity) .. GROUP BY Item_ID 如果销售是<0数量交易--补货是>0数量交易2,会更正确。


0
投票

这应该可以。虽然未经测试。

SELECT B.Item_ID
       B.Quantity - C.Quantity AS 'Quantity Left'
       B.Price * (B.Quantity - C.Quantity) AS 'Purchase Amount Left'
FROM   Transaction B 
cross apply 
  SELECT SUM(Quantity) Quantity FROM Transactions A 
  WHERE A.Item_ID = B.Item_ID AND A.Transaction_Type_ID = 2) C
WHERE B.Transaction_Type_ID = 1 AND B.Quantity > C.Quantity

0
投票

你应该可以做一些像下面的查询。正如我 完全确定你想做什么,你可能必须修改它以适应,但它至少应该是一个好的起点。

select Transaction_Type_ID, Item_ID
  , Quantity - QuantitySold
  , Value * (Quantity - QuantitySold)
from
(
  select B.Transaction_Type_ID, B.Item_ID
    , sum(case when B.Transaction_Type_ID = 1 then Quantity else 0 end) QuantityPurchased
    , sum(case when B.Transaction_Type_ID = 1 then Quantity * Price else 0 end) Value
    , sum(case when B.Transaction_Type_ID = 2 then Quantity else 0 end) QuantitySold
  from Transaction B
  group by B.Transaction_Type_ID, B.Item_ID
) x
© www.soinside.com 2019 - 2024. All rights reserved.