2015-09-07 104 views
1

使用SQL Server 2008 R2:我无法绕过更新我从WITH语句获得结果的临时表。使用WITH语句更新临时表结果

临时表,这将是我的主表,我们称之为#main,很简单,看起来像这样的第一行(将有数百个产品代码,所以我不能硬编码产品在解决方案代码):

Product | GapForGoodsinWH1 | GapForGoodsinWH2 
1000 |   NULL  |   NULL 

中的空白在那里我跑我的WITH语句之前。 WITH声明的目的是确定货物未被接收到某个仓库中的最长时间(在本示例中表示为WH1和WH2)

我的WITH声明正常工作如果我身份验证产品代码和仓库:

WITH GoodsIn AS (
    SELECT 
     Product, 
     ROW_NUMBER() OVER (ORDER BY GoodsInDate DESC) AS RN, 
     GoodsInDate 
    FROM GoodsIn 
    WHERE 
    GoodsInDate >= @StartDate 
    and GoodsInDate <= @EndDate 
    -- 
    AND Product = 1000 
    AND Warehouse = 'WH1' 
) 
SELECT 
    A.Product, 
    MAX(DATEDIFF(DD, A.GoodsInDate, B.GoodsInDate)) AS TimeMissing 
FROM 
    GoodsIn A 
LEFT JOIN 
    GoodsIn B ON A.RN = B.RN + 1 
GROUP BY 
    A.Product 
HAVING 
    MAX(DATEDIFF(DD, A.GoodsInDate, B.GoodsInDate)) >= @Missing 

所以日期参数看在一定时期内和@Missing参数是为用户列出的产品,如果他们已经失踪的时间X时间(在参数定义)。

我想要做的就是e通过在Product上进行更新,将TimeMissing值输入到我的#main表中。在这个例子中,我想通过将产品与#main.productWarehouse#main.GapForGoodsinWH1进行匹配来更新#main.GapForGoodsinWH1

任何想法都会受到欢迎,提前谢谢。

+0

您能提供GoodsIn表的结构吗?表中的同一产品可以有多个记录? – Kai

+0

Hello Kai - 是的,可以。您将拥有“产品”,“仓库”和“GoodsInDate”。也会有数量,但我并不真正对此感兴趣,这是'GoodsInDate'之间的差距分析,只要在创建日期时有一定的数量。例如,产品1000可以在八月份出现多次,该产品有一个条目,并且该表格将包含WH1和WH2的条目。您可以在同一天进行两次交付,但这并不会影响我,因为他们只会在我的CTE中返回0。 – TJB

+0

您是否可以在GapForGoodsinWH1列中清除您想要的值? – Kai

回答

1

我不知道这是否是你想要的结果,但让你想要什么我知道,如果有其不同于:

WITH GoodsIn AS(
    SELECT 
     Product, 
     ROW_NUMBER() OVER (PARTITION BY Product ORDER BY Product, GoodsInDate DESC) AS RN, 
     GoodsInDate, 
     WareHouse 
    FROM GoodsIn 
    WHERE 
    GoodsInDate >= @StartDate 
    AND GoodsInDate <= @EndDate 
    AND Product = @ID -- specidied product 
    AND WareHouse = @WareHouse -- specidied WareHouse 
) 

Update m set GapForGoodsinWH1 = TBL.TimeMissing 
From #main m 
INNER JOIN 
(
    SELECT 
     A.Product, 
     MAX(DATEDIFF(DD, A.GoodsInDate, B.GoodsInDate)) AS [TimeMissing] 
    FROM 
    GoodsIn A 
    LEFT JOIN 
    GoodsIn B ON A.Product = B.Product AND A.RN = B.RN + 1 
    GROUP BY 
    Product 
)TBL ON TBL.Product = m.Product 
WHERE TBL.TimeMissing >= @Missing 
+0

可以根据您的要求排除仓库和产品的条件。 – Kai

+0

Hello Kai - 这真是太棒了,非常感谢,并且很有效! – TJB

+0

不客气:) – Kai

-1

这应该工作:

WITH GoodsIn AS (
    SELECT 
     Product, 
     ROW_NUMBER() OVER (ORDER BY GoodsInDate DESC) AS RN, 
     GoodsIn 
    FROM GoodsIn 
    WHERE 
    GoodsIn >= @StartDate 
    and GoodsIn <= @EndDate 
    -- 
    AND Product = 1000 
    AND Warehouse = 'WH1' 
) 
Update m set GapForGoodsinWH1 = g.TimeMissing 
From #main m 
Inner Join (
    SELECT 
     A.Product, 
     MAX(DATEDIFF(DD, A.GoodsInDate, B.GoodsInDate)) AS TimeMissing 
    FROM GoodsIn A 
    LEFT JOIN GoodsIn B 
     ON A.RN = B.RN + 1 
    GROUP BY A.Product 
    HAVING MAX(DATEDIFF(DD, A.GoodsInDate, B.GoodsInDate)) >= @Missing 
) as g 
    on g.product = m.product 
+0

感谢您的回复...请原谅我,如果我很密集,但我没有在您的解决方案中定义A.RN和B.RN的位置? – TJB

+0

问题中的“with”查询不会为每个产品或每个仓库分配行号。您的“左连接”也不会使用产品或仓库作为条件。结果应该是相当随机的。 – Andomar

0

可以使用lag窗口函数查找先前的装运:

lag(GoodsInDate) over (
    partition by Product, Warehouse 
    order by GoodsInDate) 

然后,你可以查找最大dif ference在仓库每单位产品的日期,并将其存储在main

; with GoodsInWithDelta as 
     (
     select Product 
     ,  GoodsInDate 
     ,  lag(GoodsInDate) over (
        partition by Product 
        order by GoodsInDate) as PrevDate 
     from GoodsIn 
     where Warehouse = 'WH1' 
     ) 
,  MaxDeltaByProduct as 
     (
     select Product 
     ,  max(datediff(day, PrevDate, GoodsInDate)) as MaxDelta 
     from GoodsInWithDelta 
     group by 
       Product 
     ) 
update m 
set  GapForGoodsinWH1 = MaxDelta 
from main m 
left join 
     MaxDeltaByProduct mdbp 
on  m.Product = mdbp.Product 

Example at SQLFiddle.可以重复此查询第二个仓库。