如何根据生效日期选择正确的行?

时间:2014-02-03 15:24:43

标签: sql sql-server

我有以下(简明)查询开始:

WITH Product_List AS
    (SELECT J.Product_ID,
            N.Product_Name,
            J.Unit_Price,
            J.Effective_Date,
            ROW_NUMBER() OVER (PARTITION BY J.Product_ID ORDER BY J.Effective_Date DESC) AS      RowNum
    FROM Company.dbo.Pricing_File AS J
    LEFT JOIN Company.dbo.No_pricing_File AS N ON J.Product_ID = N.Product_ID)

这拉动的数据看起来就像这样:

J.Product_ID | N. Product_Name | J.Unit_Price | J.Effective_Date | RowNum
123456       | Product_1       | 12.34        | 01-04-14         | 1
123456       | Product_1       | 12.56        | 01-04-13         | 2
123456       | Product_1       | 12.80        | 01-04-12         | 3
567898       | Product_2       | 10.00        | 01-01-14         | 1
567898       | Product_2       | 9.50         | 01-01-13         | 2

我现在使用此列表从Product_Name和Unit_price列中提取数据,但查询需要根据生效日期提取正确的unit_price。以下是我的其余查询:

SELECT 
   A.*,
   B.*,
   Product_List_1.Product_Name,
   Product_List_1.Unit_Price,
FROM 
   Company.dbo.Company_Master AS A
LEFT JOIN Company.dbo.Product_Info AS B ON A.Claim_Number = B.Claim_Number AND A.Customer_Number = B.Customer_Number
LEFT JOIN Product_List AS Product_List_1 ON B.Product_ID_1 = Product_List_1.Product_ID AND
B.Fill_Date >= Product_List_1.Effective_Date AND
Product_List_1.RowNum = 1

除了一种情况外,这完全符合预期。当J.Effective_Date类似于01-04-14而B.Fill_Date类似于12-30-13时,我加入的标准不再正确。生效日期不是> =填充日期或RowNum!= 1.我尝试更改JOIN ON的最后一行:

Product_List_1.RowNum = 1 

Product_List_1.RowNum LIKE '[1-2]' 

和其他变化,但它将返回多个结果,而不是它应该唯一的结果。

我的问题是,如何根据Fill_Date和Effective_Date从Product_List表中选择正确的记录?

感谢您的帮助。如果您有任何问题或需要澄清,请与我们联系。

1 个答案:

答案 0 :(得分:1)

如果出现,您正在尝试根据生效日期的价格列表获取适用于特定索赔或订单的产品的定价。在这种情况下,我过去的做法是将您的定价加在一起,以便获得开始/结束日期而不仅仅是生效日期,并加入开始日期和结束日期。

以下是一个例子:

;WITH Product_List AS
(SELECT J.Product_ID,
            N.Product_Name,
            J.Unit_Price,
            J.Effective_Date,
            ROW_NUMBER() OVER (PARTITION BY J.Product_ID ORDER BY J.Effective_Date DESC) AS      RowNum
    FROM Company.dbo.Pricing_File AS J
    LEFT JOIN Company.dbo.No_pricing_File AS N ON J.Product_ID = N.Product_ID
  )
, ctePriceRange as
(
    SELECT 
        l1.Product_ID, 
        l1.Product_Name,
        l1.Unit_Price,
        l1.Effective_Date as PriceStart,
        l2.Effective_Date as PriceEnd
    FROM Product_List l1
    LEFT JOIN Product_List l2 
    ON l1.Product_ID = l2.Product_ID
    and l1.RowNum = l2.RowNum - 1 --Join this price up with the next available price to get the end date 
)
SELECT 
   A.*,
   B.*,
   Product_List_1.Product_Name,
   Product_List_1.Unit_Price,
FROM 
   Company.dbo.Company_Master AS A
LEFT JOIN Company.dbo.Product_Info AS B ON A.Claim_Number = B.Claim_Number AND A.Customer_Number = B.Customer_Number
LEFT JOIN ctePriceRange AS Product_List_1 ON B.Product_ID_1 = Product_List_1.Product_ID AND
B.Fill_Date >= Product_List_1.PriceStart AND 
(
    B.Fill_Date < Product_List_1.PriceEnd 
    OR 
    Product_List_1.PriceEnd is null --this handles the last effective price that is listed, which will not have an end date
)