【问题标题】:Get last purchase along with price获取最后一次购买以及价格
【发布时间】:2018-06-18 00:11:44
【问题描述】:

我想获取所选供应商的目录以及最后一次购买价格,即 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

【问题讨论】:

  • 您的查询结果是什么?
  • 它什么也不返回,因为当 idsupplier = 4 时,rn 总是不同于 1
  • 我在你的架构中没有看到 idStoreCmd
  • 我刚刚编辑了它的 idCommand,抱歉

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


【解决方案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。

如果子查询没有返回记录,则外部应用(另一个可选连接)将返回空值。如果您只对有价格的产品感兴趣,请改用 CROSS APPLY。

另请注意,此查询不会确定在以下情况下要做什么: - 同一产品的同一供应商有两个相同最后日期的命令,但成本不同 - 同一种产品在同一个司令部下销售两次,但成本不同

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

【讨论】:

  • 完美!非常感谢
【解决方案2】:

这样的事情应该可以工作:

;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 中取出一些字段并稍后将它们加入。

【讨论】:

  • 非常感谢,它正在工作,但我必须在最后一个选择中添加Distinct,因为如果没有它,例如如果 SUP1(供应商 1)在目录中有 3 个产品,我会得到相同的结果3 次,如果是 4 次,则 4 次,是否真的有必要或缺少某些东西?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多