2016-05-30 3 views
2

Прошу прощения, если это название не представляет мою проблему здесь.SQL FIFO Logic в sql server 2008

У меня есть таблица 1 с несколькими элементами.

ТАБЛИЦА 1

|No|Item|Quantity X|  
|1 |A |20  | 
|2 |A |21  | 
|3 |A |10  | 
|4 |B |3   | 
|5 |B |4   | 
... 

Моя пользовательская функция FIFO результат для элемента A:

|No|Name  |Quantity Y|   
|1 |Document1|2   | 
|2 |Document2|20  | 
|3 |Document3|5   | 
|4 |Document4|1   | 
|5 |Document5|22  |   

Моя пользовательская функция FIFO результат для элемента B:

|No|Name  |Quantity Y|   
|1 |Document100|2   | 
|2 |Document101|2   | 
|3 |Document102|4   | 

Ожидаемый результат:

ТАБЛИЦА 2

Item|Quantity X|Name  |Quantity Y| 
A |20  |Document1 |2   | 
A |20  |Document2 |18  | 
A |21  |Document2 |2   | 
A |21  |Document3 |5   | 
A |21  |Document4 |1   | 
A |21  |Document5 |13  | 
A |10  |Document5 |10  | 
B |3   |Document101|2   | 
B |3   |Document102|1   | 
B |4   |Document102|1   | 
B |4   |Document103|3   | 

У меня есть SQL Server 2008. Как достичь этого с помощью SQL?

+3

Я не понимаю связь между каждым столом .. – sagi

+1

, что делает ваша функция FIFO выглядеть? и откуда идут данные этого документа? –

+0

Возможно, вы захотите использовать ['cross apply'] (https://technet.microsoft.com/en-us/library/ms175156 (v = sql.105) .aspx), но я не вижу, как ваши данные объединяются вверх. – DaveShaw

ответ

1

У меня только один странный ответ здесь :) Пожалуйста, садитесь и смотрите.

--I use cte's to show you a sample of how it wiil work 
--Here comes table with incoming docs 
;WITH table1 as (
SELECT * 
FROM (VALUES 
(1, 'A', 20),(2, 'A', 21),(3, 'A', 10),(4, 'B', 3),(5, 'B', 4) 
)AS t([No],Item,[Quantity X]) 
--Here comes table with outgoing item A 
), itemA AS (
SELECT * 
FROM (VALUES   
(1, 'Document1',2),(2, 'Document2',20),(3, 'Document3',5),(4, 'Document4',1),(5, 'Document5',22) 
)AS t([No], Name, [Quantity Y]) 
--Here we fraction each quantity for documents in 1, 
--so if quantity is 20 there will be 20 rows with 1 
), recT1 AS (
    SELECT [No], Item, [Quantity X], 1 as [level], 1 as Qty 
    FROM table1 
    WHERE Item = 'A' 
    UNION ALL 
    SELECT [No], Item, [Quantity X], [level] +1,1 
    FROM recT1 
    WHERE [level] < [Quantity X] 
--same to items 
), recA AS (
    SELECT [No], [Quantity Y], 1 as [level], 1 as Qty 
    FROM itemA 
    UNION ALL 
    SELECT [No], [Quantity Y], [level] +1,1 
    FROM recA 
    WHERE [level] < [Quantity Y] 
--here we add ROW_NUMBER not to lost order 
), finalT1 as (
    SELECT *, ROW_NUMBER() OVER (ORDER BY [No], [Level]) as rn 
    from recT1 
), finalA as (
    SELECT *, ROW_NUMBER() OVER (ORDER BY [No], [Level]) as rn 
    FROM recA 
) 
--final query! 
SELECT t.Item, 
     t.[Quantity X], 
     ia.Name, 
     CASE WHEN a.[level] > t.[level] THEN t.[level] ELSE a.[level] END as [Quantity Y] 
FROM finalT1 t 
INNER JOIN finalA a 
    ON t.rn = a.rn 
LEFT JOIN itemA ia 
    ON ia.[No] = a.[No] 
WHERE a.[level] = a.[Quantity Y] or t.[level] = t.[Quantity X] 

Выход:

Item Quantity X Name  Quantity Y 
A  20   Document1 2 
A  20   Document2 18 
A  21   Document2 2 
A  21   Document3 5 
A  21   Document4 1 
A  21   Document5 13 
A  10   Document5 9 

Для B

Item Quantity X Name  Quantity Y 
B  3   Document100 2 
B  3   Document101 1 
B  4   Document101 1 
B  4   Document102 3 
+0

Все работает отлично! Большое спасибо. Я только добавил предложение «ОПЦИЯ (maxrecursion 0)» – Najlepszak

+0

Мое удовольствие! Не так много данных, поэтому я забыл о 'OPTION (maxrecursion 0)' :(Если это поможет быть свободным, чтобы поддержать/принять мой ответ! – gofr1