使用日期范围更新/加入

时间:2014-04-11 16:32:10

标签: sql join sql-server-2012

您好我正在尝试根据一些条件对两个表进行更新/连接。以下是我的两个表格的结构:

表1

Pricelist     Product     Price     Effective Date     Expiry Date
1             1           NULL      2012-07-01         2013-06-30
1             2           NULL      2012-07-01         2013-06-30
1             3           NULL      2012-07-01         2013-06-30   

表2

Pricelist     Product     Price     As of Date
1             1           50.00     2013-06-26
1             1           55.00     2013-07-02
1             2           77.00     2013-06-26
1             2           108.00    2013-07-02
1             3           250.00    2013-06-29 
1             3           263.00    2013-06-30
1             3           266.00    2013-07-01

正如您可能想象的那样,我需要将结果表看起来像这样:

表3

Pricelist    Product      Price     Effective Date     Expiry Date
1            1            50.00     2012-07-01         2013-06-30
1            2            77.00     2012-07-01         2013-06-30
1            3            263.00    2012-07-01         2013-06-30

除了加入价目表和产品之外,其他条件是"截至日期"在表2中必须小于或等于"到期日"在表1中。

到目前为止,这是我的代码:

UPDATE A
SET A.[Price] = B.[Price]
FROM [Table1] A 
INNER JOIN [Table2] B
ON A.[Pricelist] = B.[Pricelist]
AND A.[Product] = B.[Product]
HAVING MAX(B.[as_of_DATE]) <= A.[Expired Date]

当然这是错误的,我只是不确定使其工作的语法。提前非常感谢帮助。干杯!

3 个答案:

答案 0 :(得分:0)

尝试这样的事情,看看它是否适合你。

UPDATE [Table1]
SET [Table1].[Price] = B.[Price]
FROM (SELECT B.[Product], B.[Pricelist],
        MAX(B.[as_of_DATE]) as Max_Date
     FROM [Table2] B 
     GROUP BY B.[Product], B.[Pricelist]
) AS C
JOIN [Table2] B ON B.[Pricelist] = C.[Pricelist] 
    AND B.[Pricelist] = C.[Pricelist]
    AND B.as_of_DATE = c.Max_Date
WHERE [Table1].[Pricelist] = C.[Pricelist]
    AND [Table1].[Product] = C.[Product]
HAVING C.[Max_Date] <= [Table1].[Expired Date]

答案 1 :(得分:0)

试试这个

UPDATE t1
set t1.price = t2.price_new 
from table1 t1
inner join
(

    select a.*, 
    b.price price_new,
    row_number() over (partition by a.pricelist, a.product 
                       order by as_of_date desc) price_rank
    from table1 a
    inner join table2 b 
    on a.pricelist = b.pricelist and a.product = b.product
    where b.as_of_date between effective_dt and expiry_date
) t2 
on t1.pricelist = t2.pricelist and t1.product = t2.product and t2.price_rank = 1;

select * from table1

SQL DEMO

答案 2 :(得分:0)

这是使用CTE的另一种解决方案

;WITH CTE
AS
(
  SELECT A.price, B.price NewPrice, ROW_NUMBER() OVER(PARTITION BY A.[Pricelist], A.[Product] ORDER BY B.[as_of_DATE]) rn
  FROM [Table1] A 
  LEFT JOIN [Table2] B
  ON A.[Pricelist] = B.[Pricelist]
    AND A.[Product] = B.[Product]
    AND B.[as_of_DATE] <= A.[expiry_date]
)

UPDATE CTE SET Price = NewPrice  WHERE rn=1;

<强> SQL FIDDLE DEMO

P.S。感谢@rs。小提琴。