We are creating a inventory system for items called readoutprobes and readoutprobekits. The schema, below, is simplified, using the words items and itemkits.
An itemkit, is a predefined collection of 1 or more items, i.e. a kit. In a kit, a specific type of an item, can only occur once. A kit, typically contains ~40 items. The definition of items in a kit, is captured by the itemkit_item table. The inventory for the kits, are captured in the itemkit_containers table.
An itemkit_container do not track physical item containers. Instead, its assumed that a physical itemkit is properly 'assembled', using a set of physical items, but we don't know which ones. When populated, the 'populated' field in an itemkit_containers record, is set to true.
The inventory for items are tracked by a item_containers table. Its existence is monitored by the containers volume. When the volume is 0, the container is considered emptied.
Getting the count of physical item containers, with a volume > 0, for a specific item, is obtained from the item_container table, and the same for the kits
We want to get a 'reserved count' number for each item, reflecting the kits inventory.
For example, say we got an item, named A, having a count of 42. If we are creating an itemkit containing an item named A, and a corresponding itemkit_container, we want to have a count of 'reserved' being 1, for item A.
The 'master query' for items looks like this:
SELECT items.*,
ic.item_count
FROM items
LEFT JOIN (
SELECT p.id, COUNT(*) item_count, ic.item_id
FROM items AS p, item_containers AS ic
WHERE p.id = ic.item_id AND ic.volume > 0
GROUP BY p.id
) AS ic
ON ic.item_id = items.id
GROUP BY items.id
ORDER BY items.id;
Data in the items table:
Data in the item_containers table:
Data in the itemkits table:
Data in the itemkit_item table:
And data in the itemkit_containers:
As can be observed, the only record of an itemkit, and its inventory, contains items with item ID's = {1,3}
This question is to find out how to query for the number of 'free' (or reserved) physical items, i.e. item_containers inventory there is, at any one point in time.
The above query, returns this result:
We want an additional field, that indicate a 'Reserved' count for each item, reflecting the status of actual inventory for items and itemkits.
For the data above, this would be
A -> Reserved = 1
B -> Reserved = 0
C -> Reserved = 1
D -> Reserved = 0
A db fiddle that creates and populates the above tables is here: DB Fiddle
We are using MySQL 8.0.
NOTE: The answer below is close to correct. However, it does not relate item_containers (actual invnetory) with the itemkit_container records, but instead the itemkit records. This become clear by toggling the populated field in the itemkit_containers table to '0'. I.e.:
The output, even though the kit is no longer populated shows the same 'Reserved' count. Reserved should be equal to '0' in this case. Here is a fiddle for that case: Fiddle where Reserved should be all '0'
Thanks for such detailed description and all the necessary sample data.
As you already tried in your query you can have the item with quantity by joining items and item_containers table. For calculating free or reserved item you need to left join itemkit_containsers table since inventory for items in a kit is stored there. So just calculate the count for any item in itemkit_containers then you got your reserved quantity and by subtracting it from item_count of item_containsers table will give you free quantity for that item.
Schema and insert statements:
Query:
Output:
db<fiddle here
Db-Fiddle with with populated and not populated itemkit_containsers:
Select queries (sample data):
Output:
Query:
Output:
db<fiddle here