2015-09-07 106 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.可以重複此查詢第二個倉庫。