| Author |
Topic  |
|
|
Chenp22
Starting Member
Australia
3 Posts |
Posted - 02/23/2012 : 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/N 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,
Item - Qty HAT 100 SHOE 100 SHIRT 100
So 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/N John 13 HAT 75 Y John 13 SHOE 50 Y John 13 SHIRT 25 Y Mike 1 HAT 25 Y Mike 1 SHOE 50 Y Mike 1 SHIRT 25 Y David 30 HAT 50 N David 30 SHOE 50 N David 30 SHIRT 50 Y
|
|
|
singularity
Posting Yak Master
149 Posts |
Posted - 02/23/2012 : 19:29:36
|
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 a
join [stock on hand] b on a.item = b.item
|
 |
|
|
Chenp22
Starting Member
Australia
3 Posts |
Posted - 02/23/2012 : 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
7 Posts |
Posted - 02/23/2012 : 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
7 Posts |
Posted - 02/24/2012 : 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.
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,10 A4: 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
Australia
3 Posts |
Posted - 02/24/2012 : 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
Flowing Fount of Yak Knowledge
United Kingdom
3442 Posts |
Posted - 02/24/2012 : 05:38:49
|
Here's one way that should work on 2005. It's probably not optimal.
BEGIN TRANSACTION
CREATE 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 #Stock
VALUES
('HAT', 100)
, ('SHOE', 100)
, ('SHIRT', 100)
CREATE TABLE #workTable (
[Customer] VARCHAR(10)
, [PriorityRank] INT
, [Item] VARCHAR(5)
, [QtyRequested] INT
, [StockLevel] INT
, [CanBeDone] BIT
)
-- Populate #workTable
INSERT #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 Calculations
CREATE 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 #workTable
ROLLBACK TRANSACTION
Results
Customer PriorityRank Item QtyRequested StockLevel CanBeDone
---------- ------------ ----- ------------ ----------- ---------
Mike 1 HAT 25 75 1
John 2 HAT 75 0 1
David 3 HAT 50 -50 0
Mike 1 SHIRT 25 75 1
John 2 SHIRT 25 50 1
David 3 SHIRT 50 0 1
Mike 1 SHOE 50 50 1
John 2 SHOE 50 0 1
David 3 SHOE 50 -50 0
Charlie =============================================================== Msg 3903, Level 16, State 1, Line 1736 The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
Transact Charlie
Flowing Fount of Yak Knowledge
United Kingdom
3442 Posts |
Posted - 02/24/2012 : 06:05:49
|
Here's a way without using a worktable.
BEGIN TRANSACTION
CREATE 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 #Stock
VALUES
('HAT', 100)
, ('SHOE', 100)
, ('SHIRT', 100)
-- INDEXES TO help the report
CREATE 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 sr
ROLLBACK TRANSACTION
I'm assuming that your order and stock tables are simplified?
Charlie =============================================================== Msg 3903, Level 16, State 1, Line 1736 The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
| |
Topic  |
|
|
|