自我加入聚合函数或更好的方法

时间:2017-03-20 16:44:40

标签: sql sql-server database

我正在使用SQL-Server,并有一张我的采购订单(库存)的表格。但是当我试图以最新成本价格最新销售价格来获取所有可用股票时,我坚持查询。

我查询它运行成功,但我需要一些更好和优化的方法来执行此操作,因为当表有n个记录时,它会变慢。

查询示例:

SELECT 
    po.ProductID, sum(po.AvailableQty) as AvailableQty,
    (select top 1 po2.CostPrice from Sales_PurchaseOrders po2 where po2.PurchasedAt=max(po.PurchasedAt)) as CostPrice,
    (select top 1 po2.SellingPrice from Sales_PurchaseOrders po2 where po2.PurchasedAt=max(po.PurchasedAt)) as SellingPrice
FROM 
    Sales_PurchaseOrders po
INNER JOIN Sales_Products p on p.ProductID=po.ProductID
GROUP BY po.ProductID

表格数据

PurchaseOrderID ProductID   CostPrice                               SellingPrice                            AvailableQty                            PurchasedAt
--------------- ----------- --------------------------------------- --------------------------------------- --------------------------------------- -----------------------
1               1           90.000000                               100.000000                              2.000000                                2016-07-28 00:00:00.000
2               1           33.580000                               50.000000                               0.000000                                2016-06-28 00:00:00.000
3               2           200.000000                              240.000000                              15.000000                               2016-07-30 00:00:00.000
4               1           50.000000                               60.000000                               0.000000                                2016-08-02 00:00:00.000
5               1           50.000000                               60.000000                               1.000000                                2016-08-03 00:00:00.000
6               1           100.000000                              110.000000                              6.000000                                2016-08-04 00:00:00.000
7               1           25.000000                               30.000000                               3.000000                                2016-08-03 00:00:00.000
8               1           20.000000                               30.000000                               0.000000                                2016-07-30 00:00:00.000
1007            1           100.000000                              200.000000                              2.000000                                2016-09-24 00:00:00.000

查询结果:

ProductID   AvailableQty                            CostPrice                               SellingPrice
----------- --------------------------------------- --------------------------------------- ---------------------------------------
1           14.000000                               100.000000                              200.000000
2           15.000000                               200.000000                              240.000000

可以通过某种聚合函数,或任何其他更好的优化方式来执行此操作。

谢谢,

3 个答案:

答案 0 :(得分:3)

我认为这可以满足您的需求:

SELECT po.ProductID, sum(po.AvailableQty) as AvailableQty,
       MAX(last_CostPrice), MAX(last_SellingPrice)
FROM (SELECT po.*, 
             FIRST_VALUE(CostPrice) OVER (PARTITION BY ProductId ORDER BY PurchasedAt DESC) as last_CostPrice,
             FIRST_VALUE(SellingPrice) OVER (PARTITION BY ProductId ORDER BY PurchasedAt DESC) as last_SellingPrice
      FROM Sales_PurchaseOrders po
     ) po
GROUP BY po.ProductID;

注意:

  • 查询表Sales_Products似乎完全没必要。
  • 您可能想要产品的最新成本和销售价格,而不是所有产品。
  • 您可以在子查询中使用FIRST_VALUE()来获取此信息。

答案 1 :(得分:1)

亲爱的Mehmood试试这个。

;with wt_table 
as
(
select ROW_NUMBER() over(partition by po.ProductID order by PurchasedAt desc) as Num,
AvailableQty=sum(po.AvailableQty) over(partition by po.ProductID),
po.ProductID,
po.CostPrice,
po.SellingPrice,
po.PurchasedAt
From    #Sales_PurchaseOrders po)
select * from wt_table  where Num=1

答案 2 :(得分:0)

试试这个:

with Sales_PurchaseOrders(PurchaseOrderID,ProductID,CostPrice,SellingPrice,AvailableQty,PurchasedAt)AS(
select 1,1,90.000000,100.000000,2.000000,'2016-07-28 00:00:00.000' union all
select 2,1,33.580000,50.000000,0.000000,'2016-06-28 00:00:00.000' union all
select 3,2,200.000000,240.000000,15.000000,'2016-07-30 00:00:00.000' union all
select 4,1,50.000000,60.000000,0.000000,'2016-08-02 00:00:00.000' union all
select 5,1,50.000000,60.000000,1.000000,'2016-08-03 00:00:00.000' union all
select 6,1,100.000000,110.000000,6.000000,'2016-08-04 00:00:00.000' union all
select 7,1,25.000000,30.000000,3.000000,'2016-08-03 00:00:00.000' union all
select 8,1,20.000000,30.000000,0.000000,'2016-07-30 00:00:00.000' union all
select 1007,1,100.000000,200.000000,2.000000,'2016-09-24 00:00:00.000'
)
select * from (
    SELECT 
po.ProductID, sum(po.AvailableQty)over(partition by po.ProductID) as AvailableQty,CostPrice,SellingPrice,
row_number()over(partition by po.ProductID order by po.PurchasedAt desc) as seq
    FROM  Sales_PurchaseOrders  po

) as t where t.seq=1
    ProductID   AvailableQty    CostPrice   SellingPrice    seq
1   1   14,000000   100,000000  200,000000  1
2   2   15,000000   200,000000  240,000000  1