2015-09-07 2 views
1

Использование SQL Server 2008 R2: я не могу понять, как обновить временную таблицу, имеющую результаты из инструкции WITH.Обновление таблицы temp с результатами из инструкции WITH

Временная таблица, которая будет моей главной таблицей, назовем ее #main, достаточно проста и выглядит так, как показано на первой строке (там будут сотни кодов продуктов, поэтому я не могу жестко скопировать продукт код в растворе):

Product | GapForGoodsinWH1 | GapForGoodsinWH2 
1000 |   NULL  |   NULL 

в NULLS есть, прежде чем я бег моих с WITH заявления. Цель WITH заявления заключается в определении наиболее длительный период времени, в дни, что товар не был получен в определенный склад (обозначенное как WH1 и WH2 в этом примере.

Мой WITH оператор работает нормально, если я idenfity ProductCode и склад:

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 xport значение TimeMissing в мою таблицу #main, обновив ее на Product. В этом примере я хотел бы обновить #main.GapForGoodsinWH1, сопоставив Продукт с #main.product и Warehouse до #main.GapForGoodsinWH1.

Любые идеи приветствуются, заблаговременно.

+0

Можете ли вы предоставить структуру для стола GoodsIn? может ли быть несколько записей для одного и того же продукта в таблице? – Kai

+0

Hello Kai - Да, может быть. У вас будут 'Product',' Warehouse' и 'GoodsInDate'. Будут также количества, но меня это не очень интересует, это анализ пробелов между 'GoodsInDate', так как есть количество в день, когда будет создана запись. Например, продукт 1000 может появляться несколько раз в течение августа, где есть запись для этого продукта, а таблица будет содержать записи для WH1 и WH2. Возможно, у вас могут быть две поставки в тот же день, но это меня не беспокоит, потому что они просто вернут 0 в моем CTE. – 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' в вопросе не присваивает номера строк на продукт или на склад. Ваше 'left join' не использует продукт или склад как условие. Результат должен быть довольно случайным. – Andomar

0

Вы можете использовать lag функции окна, чтобы найти предыдущую пересылку:

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

Тогда вы можете посмотреть на максимальный DIF Ференц в датах для каждого продукта на складе, и хранить его в 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. Вы можете повторить этот запрос для второго склада.

Смежные вопросы