0

我有两个表,定义如下:

PTable:

[StartDate],    [EndDate],     [Type],     PValue
.................................................
2011-07-01      2011-07-07     001         5
2011-07-08      2011-07-14     001         10
2011-07-01      2011-07-07     002         15
2011-07-08      2011-07-14     002         20

TTable:

[Date],       [Type],     [TValue]
..................................
2011-07-01    001         11
2011-07-02    001         4
2011-07-03    001         0
2011-07-08    002         12
2011-07-09    002         12
2011-07-10    002         0

我想用 PTable 中的 PValue 更新 TTable 中的 Tvalue 列,其中 TTable 中的 [Date] 介于 PTable 中的 [StartDate] 和 [EndDate] 之间,并且 DATEDIFF(DAY,TTable.[Date],PTable.[EndDate]) 是最小值, 和 PTable.Type = TTable.Type

最终的 TTable 应该如下所示:

[Date],       [Type],     [TValue]
..................................
2011-07-01    001         11
2011-07-02    001         4
2011-07-03    001         5       --updated
2011-07-08    002         12
2011-07-09    002         12
2011-07-10    002         20       --updated

我试过的是这样的:

UPDATE [TTable] 
        SET 
        TValue = T1.PValue
        FROM TTable
        INNER JOIN PTable T1 ON 
            [Date] BETWEEN T1.StartDate AND T1.EndDate 
            AND DATEDIFF(DAY,[Date],T1.EndDate) = 
              (SELECT MIN( DATEDIFF(DAY,TTable.[Date],T.EndDate)  ) 
              FROM PTable T WHERE  TTable.[Date] BETWEEN T.StartDate AND T.EndDate
             )
            AND
            T1.[Type] = TTable.[Type]

它给了我这个错误: “在包含外部引用的聚合表达式中指定了多个列。如果正在聚合的表达式包含外部引用,则该外部引用必须是表达式中引用的唯一列。”

后期编辑:

考虑到TTable AS T和PTable AS P,更新的条件是:

1. T.Type = P.Type
2. T.Date BETWEEN P.StartDate AND P.EndDate
3. DATEDIFF(DAY,T.Date,P.EndDate) = minimum value of all DATEDIFFs WHERE P.Type = T.Type AND T.Date BETWEEN P.StartDate AND P.EndDate

后来编辑2:对不起,因为我在PTable的最后一行输入错误(2011-08-10而不是2011-07-14),最终结果是错误的。

我还设法以更简单的方式进行了更新,显然我应该从一开始就尝试过:

UPDATE TTABLE 
        SET 
        TValue = T1.PValue
        FROM TTable
        INNER JOIN PTABLE T1 ON 
            [Date] = (SELECT TOP(1) MAX(Date) FROM [TTABLE] WHERE [Date] BETWEEN T1.StartDate AND T1.EndDate)
            AND
            T1.Type = [TTABLE].Type

为此表示歉意。

4

1 回答 1

0

所以你说“DATEDIFF(DAY,TTable.[Date],PTable.[EndDate]) is minimum”这让我很困惑。如果每个类型有一个每周条目,那么对于特定的日期、类型组合,它似乎只会匹配一个。你可以试试这个:

UPDATE TTABLE 
SET TValue = T1.PValue
FROM TTable
INNER JOIN PTABLE T1 ON T1.Type = [TTABLE].Type -- find row in PTable that the Date falls between
    and [Date] BETWEEN T1.StartDate AND T1.EndDate)
where 
    TValue = (  select MIN(TValue) -- finds the lowest TValue, 0 in example
                from TTable)) 

...更新...

所以看来我第一次错误地阅读了这个问题。我原以为我们会更新 TValue 最低的 TTable 条目。不知道我是怎么得到这种印象的。似乎仍然需要检查它是否为0?

UPDATE TTable 
SET TValue = T1.PValue
FROM TTable
INNER JOIN PTable T1 ON T1.Type = TTable.Type 
    and T1.EndDate = (
        SELECT top 1 EndDate 
        FROM PTable 
        WHERE Type=TTable.Type 
        ORDER BY abs(DATEDIFF(day,TTable.Date,PTable.EndDate)) desc)
WHERE 
    TValue = 0 -- only updating entries that aren't set, have a 0

这仅适用于 PTable 中有一行 EndDate 为 7/7 或任何给定类型的行。如果类型 001 有两个条目,结束日期为 7/7,那么它将加入两个条目。此外,如果有两个条目与相关日期的距离相等,则 EndDate 7/7 和 7/13 之一都是从 7/10 开始的 3 天。如果 EndDates 相隔 7 天(每周),你应该没问题。

于 2014-08-04T13:04:40.560 回答