In the following Inventory/Order system:
- Items are Ordered/Invoiced (Stored in tblInvoice and tblInvoiceItem)
- Items are then Shipped (Stored in tblShipment and tblShipmentItem)
This allows for items in Inventory to be "Allocated":
- Stock levels are maintained in each warehouse ( 5 in warehouse A, 10
in warehouse B etc.)
- Stock level is determined by the following calculation:
LastInventoryAdjustmentQuantity + (everything that has arrived and
shipped since the last InventoryAdjustment)
THE QUESTION:
How can I write a query to return a result set of InventoryItems that
shows for each warehouse the current onhand stock?
Here is the full query that is currently being used:
(This query will not run agaisnt the provided DB code but demonstrate
what I am trying to achieve)
select
distinct i.InventoryItemID,
stock.InventoryItemAdjustmentID,
w.WarehouseID 'WarehouseID',
w.Name 'WarehouseName',
stock.CreatedDate as 'AdjustmentDate',
coalesce(stock.ActualOnHand,0) as 'AdjustmentQuantity',
(select COALESCE(sum(tblInvoiceItem.Quantity),0)
from dbo.tblInvoiceItem
inner join dbo.tblInvoice on
tblInvoice.InvoiceID = tblInvoiceItem.InvoiceID
where
tblInvoice.InvoiceTypeID = 1
and
tblInvoiceItem.InventoryItemID = i.InventoryItemID
and
tblInvoiceItem.Brokered = 0
and
tblInvoice.InvoiceStatusID in (2,3,4,5,6)) as 'TotalSold',
(select COALESCE(sum(tblShipmentItem.Quantity),0)
from dbo.tblShipmentItem
inner join dbo.tblInvoiceItem on
tblInvoiceItem.InvoiceItemID = tblShipmentItem.InvoiceItemID
inner join dbo.tblInvoice on
tblInvoice.InvoiceID = tblInvoiceItem.InvoiceID
where
tblInvoice.InvoiceTypeID = 1
and
tblInvoiceItem.InventoryItemID = i.InventoryItemID
and
tblInvoiceItem.Brokered = 0
and
tblInvoice.InvoiceStatusID in (2,3,4,5,6)) as 'TotalShipped',
(select sum(tblShipmentItem.Quantity)
from
dbo.tblShipmentItem
inner join dbo.tblInvoiceItem on
tblShipmentItem.InvoiceItemID = tblInvoiceItem.InvoiceItemID
inner join dbo.tblInvoice on
tblInvoice.InvoiceID = tblInvoiceItem.InvoiceID
where
tblInvoiceItem.InvoiceItemStatusID = 2
and
tblInvoice.InvoiceTypeID = 3
and
tblInvoiceItem.InventoryItemID = i.InventoryItemID
) as 'OnHold',
(select coalesce(sum(tblShipmentItem.Quantity),0) from
dbo.tblShipmentItem
inner join dbo.tblShipment on
tblShipment.ShipmentID = tblShipmentItem.ShipmentID
inner join dbo.tblInvoiceItem on
tblShipmentItem.InvoiceItemID = tblInvoiceItem.InvoiceItemID
where
tblShipment.ShipmentTypeID in (1,3)
and
tblShipment.FromWarehouseID = w.WarehouseID
and
tblInvoiceItem.InventoryItemID = i.InventoryItemID
and
tblShipment.ShipmentDate > coalesce(stock.CreatedDate,'1/1/2003')
) as 'InBound',
(select coalesce(sum(tblShipmentItem.Quantity),0) from
dbo.tblShipmentItem
inner join dbo.tblShipment on
tblShipment.ShipmentID = tblShipmentItem.ShipmentID
inner join dbo.tblInvoiceItem on
tblShipmentItem.InvoiceItemID = tblInvoiceItem.InvoiceItemID
where
tblShipment.ShipmentTypeID in (2,4)
and
tblShipment.FromWarehouseID = w.WarehouseID
and
tblInvoiceItem.InventoryItemID = i.InventoryItemID
and
tblShipment.ShipmentDate > coalesce(stock.CreatedDate,'1/1/2003')
) as 'Outbound',
(select coalesce(sum(tblShipmentItem.Quantity),0) from
dbo.tblShipmentItem
inner join dbo.tblShipment on
tblShipment.ShipmentID = tblShipmentItem.ShipmentID
inner join dbo.tblInvoiceItem on
tblShipmentItem.InvoiceItemID = tblInvoiceItem.InvoiceItemID
where
tblShipment.ShipmentTypeID = 3
and
tblInvoiceItem.InventoryItemID = i.InventoryItemID
) as 'TotalTransferInbound',
(select coalesce(sum(tblShipmentItem.Quantity),0) from
dbo.tblShipmentItem
inner join dbo.tblShipment on
tblShipment.ShipmentID = tblShipmentItem.ShipmentID
inner join dbo.tblInvoiceItem on
tblShipmentItem.InvoiceItemID = tblInvoiceItem.InvoiceItemID
where
tblShipment.ShipmentTypeID = 4
and
tblInvoiceItem.InventoryItemID = i.InventoryItemID
) as 'TotalTransferOutbound'
from
dbo.tblInventoryItem i
inner join dbo.tblInventory inv on
i.InventoryID = inv.InventoryID
cross join
(select Name,WarehouseID from dbo.tblWarehouse) as w
/*
inner join #temp stock on
(i.InventoryItemID = stock.InventoryItemID and w.WarehouseID =
stock.WarehouseID)
*/
inner join
(select
i.InventoryItemID,
w.WarehouseID,
(select top 1 InventoryItemAdjustmentID
from
dbo.tblInventoryItemAdjustment s
where
s.InventoryItemID = i.InventoryItemID
and
s.WarehouseID = w.WarehouseID
order by CreatedDate desc
) as InventoryItemAdjustmentID
from
dbo.tblInventoryItem i
cross join
dbo.tblWarehouse w
where
w.WarehouseID > 1) as t
ON
(i.InventoryItemID = t.InventoryItemID and w.WarehouseID =
t.WarehouseID)
left join dbo.tblInventoryItemAdjustment stock on
stock.InventoryItemAdjustmentID = t.InventoryItemAdjustmentID
where
w.WarehouseID > 1
This query returns the results I want but VERY slow and extremely
inefficent. I really hope there is a better way.
Note: The result must have each warehouse stock levels grouped by
InventoryItem becuase I use the data invdivually for each warehouse in
the application.
Thank you to anyone who can help!
Here is the CODE to create a very simplied DB as an example:
CREATE DATABASE MachDB
GO
USE MachDB
GO
CREATE TABLE [dbo].[tblInventoryAdjustment] (
[InventoryAdjustmentID] [int] IDENTITY (1, 1) NOT NULL ,
[CreatedDate] [datetime] NULL ,
[ActualOnHand] [int] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblInventoryItem] (
[InventoryItemID] [int] IDENTITY (1, 1) NOT NULL ,
[Description] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS
NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblInvoice] (
[InvoiceID] [int] IDENTITY (1, 1) NOT NULL ,
[CreatedDate] [datetime] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblInvoiceItem] (
[InvoiceItemID] [int] IDENTITY (1, 1) NOT NULL ,
[Description] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS
NULL ,
[InvoiceID] [int] NULL ,
[InventoryItemID] [int] NULL ,
[Quantity] [int] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblShipment] (
[ShipmentID] [int] IDENTITY (1, 1) NOT NULL ,
[CreatedDate] [datetime] NULL ,
[WarehouseID] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblShipmentItem] (
[ShipmentItemID] [int] IDENTITY (1, 1) NOT NULL ,
[InvoiceItemID] [int] NOT NULL ,
[ShipmentID] [int] NULL ,
[Quantity] [char] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblWarehouseID] (
[WarehouseID] [int] NULL ,
[Name] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblInventoryAdjustment] WITH NOCHECK ADD
CONSTRAINT [PK_tblInventoryAdjustment] PRIMARY KEY CLUSTERED
(
[InventoryAdjustmentID]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblInventoryItem] WITH NOCHECK ADD
CONSTRAINT [PK_tblInventoryItem] PRIMARY KEY CLUSTERED
(
[InventoryItemID]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblInvoice] WITH NOCHECK ADD
CONSTRAINT [PK_tblInvoice] PRIMARY KEY CLUSTERED
(
[InvoiceID]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblInvoiceItem] WITH NOCHECK ADD
CONSTRAINT [PK_tblInvoiceItem] PRIMARY KEY CLUSTERED
(
[InvoiceItemID]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblShipment] WITH NOCHECK ADD
CONSTRAINT [PK_tblShipment] PRIMARY KEY CLUSTERED
(
[ShipmentID]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblShipmentItem] WITH NOCHECK ADD
CONSTRAINT [PK_tblShipmentItem] PRIMARY KEY CLUSTERED
(
[ShipmentItemID]
) ON [PRIMARY]
GO |