Product Based Inventory Implementation - database

I'm working on a small inventory database project on Access 2016.
I have a problem implementing a Product table and a ProductUnit table where the following business rules are true:
One, two, or many products may be put in a special package to form a new product.
Each special package may be composed of a single product or another special-package product which itself may contain many products.
My implementation of the tables is the following:
Product
| ProductID | ProductName | ... |
| 1 | A | ... |
| 2 | A(2set) | ... |
| 3 | B | ... |
| 4 | A(2set) + B | ... |
| 5 | C | ... |
ProductUnit
| ProductID | ProductUnitID | Qty |
| 2 | 1 | 2 |
| 4 | 2 | 1 |
| 4 | 3 | 1 |
The ProductUnitID is the product or special product that makes up a specific ProductID.
Recall that a product may be composed of many products. Therefore, there may be multiple ProductUnitID's for each ProductID in the ProductUnit table.
Now, let's say that I have a Sample table where I keep a record of my products in stock.
Sample
| ID |ProductID | Qty |
| 1 | 5 | 3 |
| 2 | 4 | 1 |
| 3 | 1 | 1 |
How would I generate a query to count my inventory products assuming that I want products such as ProductID = 2, ProductName = A(2set) to be count as two products of ProductID = 1, ProductName = A?
The same would apply for ProductID = 4, ProductName = A(2set) + B where I would have one A(2set) product and one B product and the one A(2set) product will have two A products.
Additional Notes: You may disregard the following
I'm thinking of recursive queries(if there is such a thing) that would just keep breaking each special product into products until each product is just a single product. A single product does not appear in the ProductUnit table.
However, I highly doubt this is possible.

Related

flexible solution for storing multiple unit of measurement for products

I want to implement multi unit of measurement(uom) for products, where allow user to purchase in different uom.
I have table below
Products
ProductId | Name | price | active | id_supplier
1 | Food | 10.00 | 1 | 1
Units
UnitId | Name
1 | Pcs
2 | Box
3 | Carton
UnitConversion
ProductId | fromUnit | factor | toUnit | type
1 | 1 | 1 | 1 | default uom
1 | 2 | 20 | 1 | selling uom
1 | 3 | 40 | 1 | selling & packing uom
I want to store multiple unit for products and show in view for a product e.g
1 pcs = $20, 1 box = $100 .. so on.
Or should i make a uom group which consist of conversion of unit and assign to the product? Which one better?
Is there any flaws in my design or anything that I miss?

how to draw data from multiple tables?

I have 2 different tables. I need to get a name from the TMK table in table 1 as below, and I need to bring the total number from my 2nd table. I can't write join. can u help me
TMK Table;
| tmkName |
| George |
| Jacob |
flowNewStatus Table;
|statusId|
| 1 |
| 2 |
if george has number 1 status i want this join
| tmkName | |statusId|
| George | | 1 |
Before getting to possible SQL queries... from the tables you show you'd need an additional table that associates the person to status, a join table. Essentially a TMK_status table:
TMK_status table
| personID | statusID |
|----------|----------|
| 1 | 1 |
| 2 | 3 |
| 3 | 1 |
Alternatively, the statusID could be stored as a column of TMK thus,
TMK table
| personID | tmkName | statusID |
|----------|----------|----------|
| 1 | George | 1 |
| 2 | Jacob | 3 |
If by "I can't write join", you mean you don't know how, check this answer: What is the difference between "INNER JOIN" and "OUTER JOIN"? - you will need an inner join.
If, on on the other hand, you mean you can't use join statements, then you could write a subselect statement. There could be other solutions but they depend on how you decide to join/relate the 2 tables.

Insert all combinations of two tables in intermediate table in SQL Server

My situation
I'm making a site where people can reserve meeting rooms. On the reservation form for a meeting room, I've some optional field sets like below:
ID | Name
-- | ------------
1 | Catering
2 | Coffee break
3 | Drinks
Here are some example meeting rooms:
ID | Name | Location
-- | ------- | ---------
1 | Dog | Brussel
2 | Cat | Antwerpen
3 | Chicken | Brugge
4 | Cow | Gent
I'm using Microsoft SQL server 2016.
Database structure
The fieldsets from the first code block stands inside my database in the table reservationFieldsets.
The meeting rooms stands in the meetingRooms table.
There is an intermediate table named meetingRoomsReservationFieldsets.
Question
Now I'll fill meetingRoomsReservationFieldsets with all rooms and all the fieldsets like below:
RoomID | FieldsetID
------ | ----------
1 | 1
2 | 1
3 | 1
4 | 1
1 | 2
2 | 2
3 | 2
4 | 2
1 | 3
2 | 3
3 | 3
4 | 3
I've tried
I've tried to do it manually but there are a lot of rooms and too much to do that manual.
I've found it by the comments on the question. I use this code:
INSERT INTO meetingRoomsReservationFieldsets
SELECT meetingRooms.id, reservationFieldsets.id
FROM reservationFieldsets
CROSS JOIN meetingRooms

Join two Select Statements into a single row when one select has n amount of entries?

Is it possible in SQL Server to take two select statements and combine them into a single row without knowing how many entries one of the select statements got?
I've been looking around at various Join solutions but they all seem to work on the basis that the amount of columns is predetermined. I have a case here where one table has a determined amount of columns (t1) and the other table have an undetermined amount of entries (t2) which all use a key that matches one entry in t1.
+----+------+-----+
| id | name | ... |
+----+------+-----+
| 1 | John | ... |
+----+------+-----+
And
+-------------+----------------+
| activity_id | account_number |
+-------------+----------------+
| 1 | 12345467879 |
| 1 | 98765432515 |
| ... | ... |
| ... | ... |
+-------------+----------------+
The number of account numbers belonging to the first query is unknown.
After the query it would become:
+----+------+-----+----------------+------------------+-----+------------------+
| id | name | ... | account_number | account_number_2 | ... | account_number_n |
+----+------+-----+----------------+------------------+-----+------------------+
| 1 | John | ... | 12345467879 | 98765432515 | ... | ... |
+----+------+-----+----------------+------------------+-----+------------------+
So I don't know how many account numbers could be associated with the id beforehand.

Database design for eCommerce Site with filters

I am doing a project on eCommerce website, but I am unable to figure out, how to design the database schema for it. In this website, there will be products from several categories and each category has a unique set of filters for it.
Example: The 'Laptop' category has filters such as 'RAM', 'Hard disk', 'Graphics Card', whereas, in the 'Shirt' category filter is 'Fabric Type' and many more.
I have thought of 2 different schema, but I am not sure of which one to be used.
Design #1
categories
---------
id
category
filters (Here filters will be stored as hard-coded JSON)
products
--------
id
category_id
name
price
specifications (Stored as JSON which will be filters using values from categories.filters)
Design #2
categories
----------
id
category
table_name
products
--------
id
category_id
name
price
laptops
-------
id
product_id
ram
hard_disk
shirts
------
id
product_id
fabric
sleeve
Which design should I choose? or is there any better design for it?
EDIT
Here, my problem is not about multiple categories but, to integrate filters. For example if I check 'RAM 4 GB' in Laptop category, then it should show all products from Laptop category with 4 GB RAM. I can't make one table for each filter, or category as there will be more than 100 of them.
I am following #Tim Biegeleisen's design, but rather than putting everything in one table. I modified it to separate categories, products and filters.
categories
+----+----------+-----------+
| id | category | parent_id |
+----+----------+-----------+
| 1 | Computer | NULL |
+----+----------+-----------+
| 2 | Laptop | 1 |
+----+----------+-----------+
| 3 | Desktop | 1 |
+----+----------+-----------+
| 4 | Clothing | NULL |
+----+----------+-----------+
| 5 | T-Shirt | 4 |
+----+----------+-----------+
| 6 | Shirt | 4 |
+----+----------+-----------+
products
+----+-------------+-----------------+-------+
| id | category_id | name | price |
+----+-------------+-----------------+-------+
| 1 | 2 | Acer Aspire | 600 |
+----+-------------+-----------------+-------+
| 2 | 3 | Dell All-in-One | 750 |
+----+-------------+-----------------+-------+
| 3 | 6 | Lee Marc Shirt | 50 |
+----+-------------+-----------------+-------+
| 4 | 5 | Nike T-Shirt | 100 |
+----+-------------+-----------------+-------+
filters
+----+-------------+-----------------+------------+-------------+
| id | filter | value | product_id | category_id |
+----+-------------+-----------------+------------+-------------+
| 1 | RAM | 4 GB | 1 | 2 |
+----+-------------+-----------------+------------+-------------+
| 2 | Battery | Li-ion | 1 | 2 |
+----+-------------+-----------------+------------+-------------+
| 3 | HDD | 500 GB | 1 | 2 |
+----+-------------+-----------------+------------+-------------+
| 4 | RAM | 16 GB | 2 | 3 |
+----+-------------+-----------------+------------+-------------+
| 5 | HDD | 1 TB | 2 | 3 |
+----+-------------+-----------------+------------+-------------+
| 6 | Fabric | Cotton | 3 | 6 |
+----+-------------+-----------------+------------+-------------+
| 7 | Sleeve | Full | 3 | 6 |
+----+-------------+-----------------+------------+-------------+
| 8 | Size | M | 4 | 5 |
+----+-------------+-----------------+------------+-------------+
| 9 | Color | Black | 4 | 5 |
+----+-------------+-----------------+------------+-------------+
To get all filters for a category:
SELECT DISTINCT `filters`.`filter` FROM `filters` WHERE `filters`.`category_id` = 2
To know all available RAM sizes for Laptop category:
SELECT DISTINCT `filters`.`value` FROM `filters` WHERE `filters`.`category_id` = 2 AND `filters`.`filter`='RAM'
category_id in filters table can be excluded as we can get that from products table. I have added it because every time I have to get all filters, I don't have to get through products table.
I would approach your problem by treating your entire catalog as a tree, where each record represents a relationship between a parent category and a child category/product.
Products:
+----+-----------+-----------+
| id | name | child_id |
+----+-----------+-----------+
| 1 | laptops | 2 |
| 1 | laptops | 6 |
| 2 | RAM | 3 |
| 2 | RAM | 4 |
| 2 | RAM | 5 |
| 3 | RAM - 1GB | null |
| 4 | RAM - 2GB | null |
| 5 | RAM - 4GB | null |
| 6 | hard disk | null |
| 7 | shirts | 8 |
| 8 | fabrics | null |
| 9 | desktops | 2 |
| 9 | desktops | 6 |
+----+-----------+-----------+
The "root" categories are those which have no parents. Here is how you would query all the root categories:
SELECT DISTINCT(name)
FROM Products
WHERE id NOT IN (SELECT DISTINCT child_id FROM Products)
Using my contrived example this would return three id values, 1, 7, and 9, for laptops, shirts, and desktops, respectively. If you then wanted to get all parts for laptops you could use this query:
SELECT child_id FROM Products WHERE id = 1
This would return 2 and 6 for the RAM and hard disk categories. You can continue querying deeper into the tree as needed. For example, if you wanted to get all RAM products, you could do this query:
SELECT id, name FROM Products WHERE id IN (3,4,5) AND child_id IS NULL
Note carefully the use of IS NULL to identify that the record be a product and not a category, since it has no more children.
I believe that even massive e-commerce sites like Amazon and Overstock do not have a hierarchy which is more than 5-10 levels, even in the deepest cases.

Resources