获取最后一次购买以及价格

时间:2018-01-09 00:48:25

标签: c# sql sql-server greatest-n-per-group

我想获取所选供应商的目录以及最后一个购买价格,即CommandDetails表中的列Costs,如下所示:

Product (idproduct, productName)

Command (idCommand, CommandCode, CommandDate, idSupplier)

CommandDetails(idCommandDetails, idProduct, Qty, idCommand, Costs)

Supplier (idSupplier, SupplierName, SupplierAddress)

SupplierCatalog (idSupplier, idProduct)

我尝试了row_number() Over (Partition by ...)和其他方法,但我遗漏了一些东西,我的大脑说够了。

期望的结果:

--------------------------------------------------
| SupplierName| ProductName | CommandDate | Costs|
--------------------------------------------------
|    SUP1     |   P1        |  01/01/2018 | 3,06 |
|    SUP1     |   P6        |  01/01/2018 | 1,65 |
|    SUP1     |   P8        |  03/01/2018 | 5,20 |
|    SUP1     |   P9        |  05/01/2018 | 8,00 |
|    SUP1     |   P10       |  01/01/2018 | NULL |
--------------------------------------------------

从未订购产品时,P10的成本为空。

我的最后一次尝试:

SELECT 
*
FROM
(SELECT 
    Sct.idsupplier,
    SCt.idProduct,
    SCD.PurchasePriceCmd Costs,
    SCD.Qty,
    P.ProCode,
    P.ProName, 
    Row_number() OVER(PARTITION BY Sct.idProduct order by P.ProCode) rn
FROM SupplierCatalog SCt
    LEFT JOIN CommandDetails SCD
        ON SCD.idProduct = SCat.idProduct 
    LEFT JOIN Command a
        ON a.idCommand = SCD.idCommand
    LEFT OUTER JOIN StoreCommand b
        ON a.idCommand = b.idCommand
    INNER JOIN Product P
        ON P.idProduct = SCt.idProduct) t
where Sct.idSupplier = 4 and rn = 1

2 个答案:

答案 0 :(得分:1)

你也可以试试这个:

SELECT 
    s.supplierName,
    p.productName,
    latestCommandDetail.CommandDate,
    latestCommandDetail.Costs
FROM Supplier s
INNER JOIN SupplierCatalog sc ON sc.idSupplier = s.idSupplier
INNER JOIN Product p ON p.idProduct = sc.idProduct
OUTER APPLY
  (
        SELECT TOP 1
            c.CommandDate,
            cd.Costs
        FROM Command c
        INNER JOIN CommandDetails cd ON cd.idCommand = c.idCommand
        WHERE c.idSupplier = s.idSupplier AND cd.idProduct = p.idProduct
        ORDER BY c.CommandDate DESC
    ) latestCommandDetail
WHERE s.idSupplier = 4
ORDER BY 
    s.supplierName,
    p.productName

我目前没有在此计算机上安装SQL Server,因此您可能需要调整语法。诀窍就是做一个子查询的链接,该子查询返回按降序日期排序的顶行。

我假设根据上面的示例代码,“SUP1”的idSupplier为4。

如果没有从子查询返回记录,则OUTER APPLY(其他可选连接)将返回空值。如果您只对价格有问题的产品感兴趣,请使用CROSS APPLY。

另请注意,如果出现以下情况,此查询无法确定: - 对于同一产品,同一供应商的同一个最后日期有两个命令但具有不同的成本 - 同一产品在相同的命令下销售两次但成本不同

在这两种情况下,这可以通过扩展子查询的排序顺序或通过分组/聚合子查询来处理。

答案 1 :(得分:0)

这样的事情应该有效:

;with cte as (
select a.idCommand, b.idProduct, row_number() over (partition by b.idProduct 
order by a.CommandDate desc) as rn, a.CommandDate, b.Costs 
from Command a
inner join CommandDetails b on a.idCommand = b.idCommand
)
select
c.SupplierName, e.productName, cte.CommandDate, cte.Costs
from Supplier c
left join SupplierCatalog d on c.idSupplier = d.idSupplier
left join Product e on d.idProduct = e.idproduct
left join cte on e.idProduct = cte.idproduct and cte.rn = 1
where c.idSupplier = @SupplierNumber;

您可以使用子查询替换顶部的公用表表达式,或者从CTE中取出一些字段并在以后加入它们。