Эффективный T-SQL для добавления отсутствующих дат с предыдущим значением - PullRequest
0 голосов
/ 21 января 2012

У меня есть таблица, которая показывает изменения инвентаря для предметов, например:

Item_ID | Date_ID   | Change | Inventory
 521    | 5/1/2010  | 56     | 56
 634    | 5/2/2010  | -12    | 42
 521    | 5/12/2010 | 3      | 59

У меня есть таблица LU_Date и таблица LU_Item со всеми предметами (которые могут или не могут присутствовать в таблице инвентаря.)

Мне нужен вывод, который показывает все даты для всех элементов, с Инвентаризацией в этот день, например:

Item_ID | Date_ID   | Change | Inventory
521     | 4/30/2010 | 0      | 0
521     | 5/1/2010  | 56     | 56
521     | 5/2/2010  | 0      | 56
521     | 5/3/2010  | 0      | 56
521     | 5/4/2010  | 3      | 59
634     | 4/30/2010 | 0      | 54
634     | 5/1/2010  | 0      | 54
634     | 5/2/2010  | -12    | 42
632     | 4/30/2010 | 0      | 0

Я пытался найти решение, но не могу найти эффективныйзапрос.При использовании решения, такого как это:

SELECT d.Date_ID,
ISNULL(r.Change,0) AS mnmt,
COALESCE(r.Inventory, S.Inventory) AS quantity
FROM dbo.LU_Date d 
CROSS JOIN LU_Item i
LEFT JOIN Fact_Inventory_ByDay r ON d.Date_ID=r.Date_ID AND r.Item_ID=i.Item_ID
OUTER APPLY (SELECT TOP(1) Inventory
           FROM Fact_Inventory_ByDay b2 
           WHERE b2.Item_ID=i.Item_ID AND b2.Date_ID < d.Date_ID 
           ORDER BY b2.Date_ID DESC, b2.Item_ID DESC) AS S
    WHERE i.item_ID=@Item

я получаю недопустимое время ожидания (например, 46 секунд для одного элемента).У кого-нибудь есть элегантное решение для меня?

Спасибо!

1 Ответ

0 голосов
/ 21 января 2012

Самая быстрая оптимизация, о которой я могу подумать, - это перенести выборку недостающих строк инвентаризации во второй запрос, который выполняется только для нужных строк.

Дайте этому шанс (это от руки, поэтому, вероятно, будут заполнены ошибками)

Я предполагаю, что первичным ключом Fact_Inventory_ByDay является Inventory_ByDay_ID, также не было уверенности в том, что в один и тот же день может произойти несколько изменений инвентаря, поэтому учел это.

SELECT
    D.Date_ID,
    I.Item_ID,
    COALESCE(SUM(FI.Change),0) AS Change,
    MAX(FI.Inventory_ByDay_ID) as MaxID,
INTO #TempRows
FROM
    dbo.LU_Date D
    JOIN LU_Item I
      ON I.Item_ID = @ItemID
    LEFT JOIN Fact_Inventory_ByDay FI
      ON FI.Date_ID = D.Date_ID AND FI.Item_ID = I.Item_ID
GROUP BY
    D.Date_ID,
    I.Item_ID


UPDATE
    #TempRows T
SET
    T.MaxID = ( SELECT TOP 1 FI.Inventory_ByDay_ID 
                FROM Fact_Inventory_ByDay FI
                WHERE FI.Date_ID < T.Date_ID
                AND FI.Item_ID = T.Item_ID
                ORDER BY FI.Date_ID DESC )
WHERE
    T.MaxID is NULL


SELECT
    T.Date_ID,
    T.Item_ID,
    T.Change,
    FI.Inventory
FROM 
    #TempRows
    JOIN Fact_Inventory_ByDay FI
      ON FI.Inventory_ByDay_ID = T.Inventory_ByDay_ID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...