POS Database Layout - sql

Our current database layout for store inventory includes a table that houses a record for each item and includes the item attributes such as price, cost, description, SKU, etc. Each store then has a table that has the SKU and the Quantity, and a few other attributes that are different for each store depending on the SKU.
Although this is better than having a column for each store's quantity in the Items table, it seems that this too is a somewhat ugly solution as when a new store is added, you need to select into a new table and when a new item is added, you have to insert into not only the items table but each individual store table.
Is there a better way to go about this than how I'm seeing it? It feels like there is.

Why not have a stock table with SKU, StoreId and Stock levels?
e.g.
Sku | StoreId | StockLevel
1234 | 001 | 15
1235 | 001 | 16
1234 | 002 | 8
1235 | 002 | 0
so, store 002 is out of stock of sku 1235, but store 001 has plenty. This table layout also allows you to get a group-wide view of your stock levels in a single table using something like
select sku, sum(StockLevel) from stock group by sku

By following the rules of data normalization, you would want to create a table like this:
store_id | sku | quantity | other_attributes ...
---------+--------+----------+---------------------
1000 | 129832 | 234 | ...
1000 | 129833 | 334 | ...
1000 | 129834 | 23 | ...
1001 | 129832 | 0 | ...
1001 | 129833 | 12 | ...
1001 | 129834 | 10 | ...
...
Essentially, it is a store_inventory table. That way, you can filter down to a given store by saying
WHERE store_id = 1000
etc...

You really want three tables as far as I can see:
Product
ProductID
Price
Description
...
StoreProduct
ProductID
StoreID
Quantity
...
Store
StoreID
Address
...
That's a perfectly valid and normalised database design, and sounds basically what you have right now.

It sounds like it started on the right path with having one table for all of the common attributes of the item.
Instead of having an individual table for each store, the inventory counts for all stores should be in a single additional table, using the Item's Key and the Store's Key as a combined Primary Key on that table.
For Example
Items
ItemKey
Name
Price
SKU
Stores
StoreKey
Name
Address
Inventory
StoreKey
ItemKey
Quantity
Using the StoreKey and ItemKey together on the Inventory table will keep your records unique.
This will allow you to not only easily lookup the single item but also lookup such things as:
Quantity of all items at one store by the StoreKey
Quantity of one item at all stores by the ItemKey
What items are low at all stores by Quantity
etc

Related

How to deal with a 'self' relationship in SQL?

In our application, we have clients and each client has a list of customers
client table:
id | name
-------------
1 | happy
2 | bashful
customer table:
id | client_id | name
----------------------------------------
50 | 1 | happys first customer
51 | 1 | happys second customer
52 | 2 | bashfuls first customer
Without going into too much detail, each client is going to have a list of prices that apply to them. For simplicity's sake, we'll say we also have a product table with product ids 1,2 and 3, and every customer will have a unique price against each item. So customer 50 will have 3 rows, customer 51 will have 3 rows, and customer 52 will have 3 rows in this price table.
price table:
id | customer_id | product_id |
----------------------------------------
50 | 50 | 1 | 4.99
51 | 50 | 2 | 6.20
52 | 50 | 3 | 8.00
...
Now here's the kicker: each client should also have their own rows on this price table. We'll refer to this client price list as the 'base list', because in the context of the app it's what all the customer prices will be compared against.
There are three immediately obvious solutions to me, but I'm not sure if any of them are right, or which one is optimal:
Solution 1
Add a row into the customer table where the name is something like 'self', so that 'self' can be treated almost like a client
.
Solution 2
Make the price table have two foreign key columns, one with customer_id and one with client_id, and allow customer_id to be null -- if customer_id is null, I know that row is the client row.
.
Solution 3
Have 2 price tables that are basically identical, one to foreign-key into customers and one to foreign-key into clients.
It is a good idea to declare foreign key relationships. No database that I know of supports a conditional foreign key relationships, so that eliminates having one column for both clients and their customers.
You have not specified if customers are unique to clients, so let me assume that they are not.
That suggests that Options 2 and 3 are the most reasonable. There is actually little to separate them. With a single table, you want a check constraint that exactly one of the ids is set -- unless you have customers shared across clients and you are allowing client-specific, customer-specific, and customer-client specific prices.
The more important consideration, I think, is that prices and relationships change over time. You should be thinking about how to incorporate effective and end dates into the data model to capture this information.

Split a row into multiple rows based on a column value

I am trying to split a record in a table to 2 records based on a column value. The input table displays the 3 types of products and their price. For a specific product (row) only its corresponding column has value. The other columns have Null.
My requirement is - whenever the product column value (in a row) is composite (i.e. has more than one product, e.g. Bolt + Brush), the record must be split into two rows - 1 row each for the composite product types.
So, in this example, notice how the 2nd row (in the input) gets split into 2 rows -> 1 row for "Bolt" and another for the "Brush", with their price extracted from their corresponding columns (i.e in this case, "Bolt" = $3.99 and "Brush" = $6.99)
Note: For composite product values there can be at most 2 products as shown in this example (e.g. Bolt + Brush)
CustId | Product | Hammer | Bolt | Brush
--------------------------------
12345 | Hammer | $5.99 | Null | Null
53762 | **Bolt+Brush** | Null | $3.99 | $4.99
43883 | Brush | Null | Null | $4.99
I have tried creating 2 predetermined records via UNION ALL using a CTE and then main_table Left Outer Join with CTE, so that the join yields 2 records instead.
#CustId | Product | Price #
12345 | Hammer | $5.99
**53762** | **Bolt** | $3.99
**53762** | **Brush** | $4.99
43883 | Brush | $4.99
This has to be solved by Spark-SQL only.
I think this will work:
select CustId, 'Hammer' as product, Hammer
from t
where Product like '%Hammer%'
union all
select CustId, 'Bolt' as product, Bolt
from t
where Product like '%Bolt%'
union all
select CustId, 'Brush' as product, Brush
from t
where Product like '%Brush%';
This would work also
select custid, product,
case when product like '%Hammer%' then hammer
when product like '%Bolt%' then bolt
else brush end as Price from
(select custid, explode(split(product,'\\+')) as product, hammer, bolt, brush
from t) x;

MS ACCESS - cannot subtract returned values from a query from values in another table

I have two tables: Project and Invoice
Project Table:
ID | UR_No | Budget_Total | Budget_To_Date
1 | 329000 | 150000.00 |
2 | 403952-C | 33000 |
Invoice Table:
ID | URID | InvAmount
1 | 329000 | 157.00
2 | 329000 | 32.00
3 | 403952-C| 193.00
Invoice table has amounts charged to a project. A project has a unique UR number (UR_No) and invoices have duplicate UR numbers (URID), meaning the same project gets billed monthly and has different invoice numbers.
What I would like to achieve is:
ID | UR_No | Budget_Total | Budget_To_Date
1 | 329000 | 150000.00 | 149811.00
2 | 403952-C | 33000 | 32807
First, an aggregate query is done on the Invoice table to get the running total of money charged to the project:
SELECT Invoice.URID, Sum(Invoice.InvAmount) AS total
FROM Invoice
GROUP BY Invoice.URID;
This returns the following:
URID | InvAmount
329000 | 189.00
403952-C| 193.00
This is then exported to a table in the DB named Invoice_Totals
I then want to join the Invoice_Totals table to the Project table using UR_No & URID and calculate an empty existing field "Budget_to_Date" in the Project table by subtracting Invoice_Totals.total in the query table from a field named Budget_total in the project table. Before attempting that, I would just like the query to return the values:
SELECT Project.Budget_Total - Invoice_Totals.total
FROM Project INNER JOIN Invoice_Totals ON Project.UR_No = Invoice_Totals.URID;
This returns the error:
Cannot join on Memo, OLE, or hyperlink object (Project.UR_No=Invoice_Totals.URID)
I looked up an SO post and tried using left 255:
SELECT Project.Budget_Total - Invoice_Totals.total
FROM Project INNER JOIN Invoice_Totals ON left(Project.UR_No,255) = left(Invoice_Totals.URID, 255);
This returns nothing. If possible, How can I subtract the aggregate field from budget total in the Project table in either the Budget_To_Date field or in a new field?
Your comment states linking fields are LongText which is synonymous with Memo data type, therefore the error message clearly identifies cause. Change the field type to ShortText.
However, really should use ID field in Project table as primary key and save that instead of UR_No into Invoice table. Numbers are more efficient keys.

Database design for products with multiple units

I am designing a database for retail business using Sql server as backend. There are some products that can be sold in multiple units, for example, pencils can be sold in ea and dozen, paper can be sold in sheet, ream, and canton. Basically, each product can be sold in more than one unit.
The App needs to supports
Can receive products from suppliers in many unit. Sometime we might
order 1 pencil and the next time we order 2 boxes of pencil.
Can sell products in multiple unit, for example, we must be able to
sell 1 box and 2 pencils in the same bill.
App also need supports for FIFO or LIFO
Below is my initial design
Table: Products
ProductId | Barcode | Name | BaseUnitId
1 | XXXX | Pencil | 1
Table: Units
UnitId | Name
1 | Each / Pieces
2 | Box
Table: UnitConversion
ProductId | BaseUnitId | Multiplier | ToUnitId |
1 | 1 | 24 | 2 | // 24 pencils in a box
Table: Inventories
Id | ProductId | UnitId | Quantity
1 | 1 | 1 | 48 //In pieces
Table Invoices
Id | ProductId | UnitId | Quantity
1 | 1 | 2 | 1.5 //Sold/Purchased 1.5 boxes that means 18 pieces
Is there any flaws in my design? Is there anything that I miss? This can't be a new problem. Does anyone have any ideas (or examples)?
I have a few suggestions:
It seems like you could remove the UnitConversion table and just store the Multiplier value against the Unit record (so you'd store 1 against Each / Pieces and 24 against Box). Then the conversion would just be the 'From' unit's quantity divided by the 'To' unit's quantity.
Is is possible that different units would have different barcodes? If so, the barcode could be stored against the Unit record instead.
In your Inventories and Invoices tables, the ProductId column might be unnecessary as you could get this by joining Units table.
To support FIFO or LIFO, you're going to need to store more specific information about your stock, so there's some way of knowing the date it was booked in, the quantity remaining, and maybe some way of identifying that specific item (or group of items).
Hope this helps!
EDIT: Your Inventories table could look something like this:
Id | UnitId | [identifier] | CurrentQuantity | DateAdded
1 | 1 | ABC123 | 20 | 2017-01-10
2 | 1 | ABC124 | 96 | 2017-01-12
The [identifier] column (name's up to you!) would store some way of identifying the physical stock, this could be something that the users assign on receipt of the item, or maybe their suppliers would already have added some that could be used.
To implement FIFO in a scenario where someone wants to buy 24 pencils, you know you need to take 20 from the group of items labelled 'ABC123' and 4 labelled 'ABC124'.

MS Access 2010 Form Data Entry- Adding the Same Field to Multiple Entries

I created a table to keep track of shipments and the invoices associated with them. I'd prefer my table to be set up as below so that I can easily draw relations off of the invoice number column.
Shipment Table
``````````````
Field Name | Data Type
----------------+-------------
ID | Autonumber or Concat
Ship Date | Date
Shipper | List Lookup
Invoice Number | Text
Often times there are multiple invoices on one shipment ID, so in the form I would need the ID, Ship Date, and Shipper fields to be input for multiple Invoice Number records.
I'm not very handy with VBA, and the macro builder doesn't seem to be able to do what I want without going into VBA anyways. How would I tackle this using VBA?
Sample Data
```````````
ID | Ship Date | Shipper | Invoice Number
-------+--------------+---------+-----------------
13597 | 5/15/2015 | UPS | 230136
13597 | 5/15/2015 | UPS | 230137
13597 | 5/15/2015 | UPS | 230138
Form Design: http://i.stack.imgur.com/vyjLF.jpg