| Author |
Topic |
|
Chenp22
Starting Member
3 Posts |
Posted - 2012-02-23 : 19:18:30
|
| Hi all, I am wondering what you would suggest as a best angle to answer the following query. I have a Orders table, with the following columns,Customer - Priority - Item - Qty - Can Order be Fulfilled Flag? Y/NJohn 13 HAT 75 John 13 SHOE 50John 13 SHIRT 25Mike 1 HAT 25Mike 1 SHOE 50Mike 1 SHIRT 25David 30 HAT 50David 30 SHOE 50David 30 SHIRT 50I also have a Stock On Hand table that has the following,Item - QtyHAT 100SHOE 100SHIRT 100So basically I need to create a query, that orders the order table by the priority(because Mike gets his orders filled before John and David). Then I need to determine if the order is able to be fulfilled based on the Stock on hand for that product. Obviously it would need to be a running stock on hand total to ensure the prior orders have been subtracted from the previous order. The end result would look something like this. Any of your advice is greatly appreciated. Customer - Priority - Item - Qty - Can Order be Fulfilled Flag? Y/NJohn 13 HAT 75 Y John 13 SHOE 50 YJohn 13 SHIRT 25 YMike 1 HAT 25 YMike 1 SHOE 50 YMike 1 SHIRT 25 YDavid 30 HAT 50 NDavid 30 SHOE 50 NDavid 30 SHIRT 50 Y |
|
|
singularity
Posting Yak Master
153 Posts |
Posted - 2012-02-23 : 19:29:36
|
| [code]select a.customer, a.priority, a.item, a.qty, case when sum(a.qty) over (partition by a.item order by a.priority) <= b.qty then 'Y' else 'N' end as [Can Order Be Fulfilled Flag?]from orders ajoin [stock on hand] b on a.item = b.item[/code] |
 |
|
|
Chenp22
Starting Member
3 Posts |
Posted - 2012-02-23 : 20:51:05
|
| Thanks for your reply. I am getting an incorrect syntax near 'order'Any idea why I might be getting that? |
 |
|
|
X002548
Not Just a Number
15586 Posts |
|
|
datakeyword
Starting Member
10 Posts |
Posted - 2012-02-23 : 22:25:58
|
| hi,singularity partition by a.item order by a.priority----Sorry,but tt seems some unreasonable for there are a "sum" before it. The aggregate function does not need a "order". |
 |
|
|
datakeyword
Starting Member
10 Posts |
Posted - 2012-02-24 : 01:19:05
|
This problem should need complecated nested SQL, I had solved it with a simple SQL plus a free tool, esProc.see below. http://static.panoramio.com/photos/original/67352228.jpg "/> Please note the right part of this image, is that correct?A1: a simple sql, I think there need no comment.A2: group by item, then sort by Priority in every group.A3: add up qty to addup field in every group. e.g. 1,2,3,4 to 1,3,6,10A4: add a new column, if addup<=stockqty then Y,else N.check http://www.esproc.com/library/product/bid-farewell-to-stored-procedure.html for more detail |
 |
|
|
Chenp22
Starting Member
3 Posts |
Posted - 2012-02-24 : 02:09:35
|
| Hi X002548, Yes, I am using SQL Server 2005. Hi datakeyword,Thanks for your reply. I was really hoping to only use SQL Server to achieve this. If no one else can solve it using SQL Server, I'll take a look. |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2012-02-24 : 05:38:49
|
Here's one way that should work on 2005. It's probably not optimal.BEGIN TRANSACTIONCREATE TABLE #Orders ( [Customer] VARCHAR(10) , [Priority] INT , [Item] VARCHAR(5) , [Qty] INT )INSERT #Orders VALUES ('John', 13, 'HAT', 75) , ('John', 13, 'SHOE', 50) , ('John', 13, 'SHIRT', 25) , ('Mike', 1, 'HAT', 25) , ('Mike', 1, 'SHOE', 50) , ('Mike', 1, 'SHIRT', 25) , ('David', 30, 'HAT', 50) , ('David', 30, 'SHOE', 50) , ('David', 30, 'SHIRT', 50)-- I also have a Stock On Hand table that has the following,CREATE TABLE #Stock ( [Item] VARCHAR(5) , [Qty] INT )INSERT #StockVALUES ('HAT', 100) , ('SHOE', 100) , ('SHIRT', 100)CREATE TABLE #workTable ( [Customer] VARCHAR(10) , [PriorityRank] INT , [Item] VARCHAR(5) , [QtyRequested] INT , [StockLevel] INT , [CanBeDone] BIT )-- Populate #workTableINSERT #workTable ([Customer], [PriorityRank], [Item], [QtyRequested], [StockLevel])SELECT o.[Customer] , ROW_NUMBER() OVER ( PARTITION BY o.[Item] ORDER BY [Priority] ) AS [PriorityRank] , o.[Item] , o.[Qty] , s.[Qty]FROM #Orders AS o JOIN #Stock AS s ON s.[Item] = o.[Item]/*** Do the work ***************************************************************************/-- Do the calculations-- INDEX FOR THE CalculationsCREATE INDEX IX_StockOrder ON #workTable ([ITEM], [PriorityRank]) INCLUDE ([QtyRequested])UPDATE wt SET [StockLevel] = CASE WHEN pOrders.[tQty] IS NULL THEN [StockLevel] - wt.[QtyRequested] ELSE [StockLevel] - wt.[QtyRequested] - pOrders.[tQty] END FROM #workTable AS wt OUTER APPLY ( SELECT SUM([QtyRequested]) AS [tQty] FROM #workTable AS wt2 WHERE wt2.[ITEM] = wt.[ITEM] AND wt2.[PriorityRank] < wt.[PriorityRank] ) AS pOrders -- And update whether it's possible to fulfill the request. UPDATE #workTable SET [CanBeDone] = CASE WHEN [StockLevel] < 0 THEN 0 ELSE 1 END SELECT * FROM #workTableROLLBACK TRANSACTION ResultsCustomer PriorityRank Item QtyRequested StockLevel CanBeDone---------- ------------ ----- ------------ ----------- ---------Mike 1 HAT 25 75 1John 2 HAT 75 0 1David 3 HAT 50 -50 0Mike 1 SHIRT 25 75 1John 2 SHIRT 25 50 1David 3 SHIRT 50 0 1Mike 1 SHOE 50 50 1John 2 SHOE 50 0 1David 3 SHOE 50 -50 0 Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2012-02-24 : 06:05:49
|
Here's a way without using a worktable.BEGIN TRANSACTIONCREATE TABLE #Orders ( [Customer] VARCHAR(10) , [Priority] INT , [Item] VARCHAR(5) , [Qty] INT )INSERT #Orders VALUES ('John', 13, 'HAT', 75) , ('John', 13, 'SHOE', 50) , ('John', 13, 'SHIRT', 25) , ('Mike', 1, 'HAT', 25) , ('Mike', 1, 'SHOE', 50) , ('Mike', 1, 'SHIRT', 25) , ('David', 30, 'HAT', 50) , ('David', 30, 'SHOE', 50) , ('David', 30, 'SHIRT', 50)-- I also have a Stock On Hand table that has the following,CREATE TABLE #Stock ( [Item] VARCHAR(5) , [Qty] INT )INSERT #StockVALUES ('HAT', 100) , ('SHOE', 100) , ('SHIRT', 100)-- INDEXES TO help the reportCREATE INDEX IX_ORders_report ON #orders ([ITEM], [PRIORITY]) INCLUDE ([Qty]); WITH OrderStock AS ( SELECT o.[Customer] , o.[Item] , o.[Priority] , o.[Qty] AS [OrderQty] , s.[Qty] AS [StockLevel] FROM #Orders AS o JOIN #Stock AS s ON s.[Item] = o.[Item] )SELECT sr.[Customer] , sr.[Item] , sr.[OrderQty] , sr.[Priority] , sr.[StockLevel] , sr.[StockRunningTotal] , CASE WHEN sr.[StockRunningTotal] < 0 THEN 'N' ELSE 'Y' END AS [CanBeDone]FROM ( SELECT os.[Customer] , os.[Item] , os.[OrderQty] , os.[Priority] , os.[StockLevel] , os.[StockLevel] - ISNULL(pOrders.[tQty], 0) - os.[OrderQty] AS [StockRunningTotal] FROM OrderStock AS os OUTER APPLY ( SELECT SUM(osprev.[OrderQty]) AS [tQty] FROM OrderStock AS osprev WHERE osprev.[ITEM] = os.[ITEM] AND osprev.[Priority] < os.[Priority] ) AS pOrders ) AS srROLLBACK TRANSACTION I'm assuming that your order and stock tables are simplified?Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
|
|
|