2016-05-30 88 views
2

如果那个标题不代表我的问题在这里,我很抱歉。在sql server 2008中的SQL FIFO逻辑

我有表1与多个项目。

表1

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

项目A我定制的FIFO功能结果:

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

为B项我定制FIFO功能结果:

|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

它工作正常!十分感谢。我只添加子句'OPTION(maxrecursion 0)' – Najlepszak

+0

我的荣幸!没有太多的数据 - 所以我忘了'OPTION(maxrecursion 0)':(如果它有助于免费上/接受我的答案! – gofr1