首页 > 解决方案 > SQL Join 与修订日期的表

问题描述

我即将开始使用 SQL 为我的公司开发一个解决方案,该解决方案要求我根据 SKU 编号链接产品类别映射。问题是类别映射可以更改,并且它们将具有与更改相关联的日期。

例如:

最终,我需要将产品的销售额分配到销售发生时它所在的类别。

我想我可以像下面这样加入:

SELECT 
   A.TransactionDate,
   A.Product,  
   B.Category, 
   SUM(A.Sales) AS TotalSales 
FROM Products AS A 
JOIN CategoryMappings AS B ON 
   A.Product=B.Product AND 
   A.TransactionDate>=B.RevisionDate 
GROUP BY A.TransactionDate, A.Product, B.Category

这假设我正在获取每个月的销售额和类别映射,并且每个月的交易都发布到月底日期(“2018 年 1 月 31 日”、“2019 年 4 月 30 日”等)。不幸的是,如果只有一个映射更改,则此 Join 仅适用于最新事务,但是如果像示例中那样有三个或更多,该怎么办?如果我想根据 2018 年的映射来查看 2018 年的销售额,因为它夹在其他两个映射之间,该怎么办?

我以前使用过 Stack Overflow,但这是我的第一个问题,如果它缺少信息或格式不正确,请原谅我。

感谢您提供的任何帮助!

标签: sqlsql-serverjoinmappingrevision-history

解决方案


如果无法根据样本数据进行验证,则不确定。

但我认为 NOT EXISTS 可能会限制为最近的修订版。

SELECT 
   P.TransactionDate,
   P.Product,  
   CatMap1.Category, 
   SUM(P.Sales) AS TotalSales 
FROM Products AS P
JOIN CategoryMappings AS CatMap1 
  ON CatMap1.Product = P.Product 
 AND CatMap1.RevisionDate <= P.TransactionDate

WHERE NOT EXISTS
(
    SELECT 1
    FROM CategoryMappings AS CatMap2
    WHERE CatMap2.Product = P.Product
      AND CatMap2.RevisionDate <= P.TransactionDate
      AND CatMap2.RevisionDate > CatMap1.RevisionDate
)

GROUP BY P.TransactionDate, P.Product, CatMap1.Category

ACROSS APPLY可能也有效

SELECT 
   P.TransactionDate,
   P.Product,  
   CatMap.Category, 
   SUM(P.Sales) AS TotalSales 
FROM Products AS P
CROSS APPLY
(
    SELECT TOP 1 CM.Category
    FROM CategoryMappings AS CM
    WHERE CM.Product = P.Product 
      AND CM.RevisionDate <= P.TransactionDate
    ORDER BY CM.RevisionDate DESC
) CatMap
GROUP BY P.TransactionDate, P.Product, CatMap.Category

推荐阅读