I'm currently working on a database for a company, for them to use when making production orders. A report is to be made consisting of several things, mainly product number, order number etc etc. A part of the report is to be made up of a list of spare parts needed for the production of the item in question. I have a table with an order number and product number, which needs to look in another table to find the necessary spare parts. However, the name, location and stock of those spare parts are in a third table, and I can't seem to find a way to include these things automatically when the product number is known. I'm pretty new to MS Access, so any help will be greatly appreciated. Thanks!
I have a table called Table1, which uses a combobox to automatically fill boxes such as production time, test time etc from a given product number. This data is gathered from the second table StandardTimes, which has as a primary key the product number. Other columns in this table includes production area, standard quantity, average production time, and also includes in several columns, the necessary spare parts needed. In a third table called Inventory, we have the product numbers of the spare parts, their location in storage, and number of items currently in store. I created a report using a query which takes an order number, and creates a report on that order number from Table1. What needs to be included in this report is a list of the spareparts necessary, the location in the storage, and the number of items currently in store.
Revised from new user input
Your question still does not provide actual columns or data. As a result, it's hard to model your needs.
However, based on what I can read, I think that you have are missing some basic design setup items in a relational model.
Assuming that you have 3 tables: Table1 (Orders), StandardTimes (Products) and Inventory (SpareParts)
In English, every order has one or more products. Every product has one or more spare parts. Really you'd want an orders table, and an order details table which has records for each item as part of that order. But I'm answering it on your setup which I believe is flawed.
Orders <-(1:M)-> Products <- (1:M) -> SpareParts
You have an OrderID, a ProductID, and a SparePartID.
A query such as this would join those 3 tables together with that kind of relationship.
SELECT o.OrderNum, o.ProductNum, st.ProductionArea, st.StandardQuality, i.SparePartsNum, i.Location, i.Qty
FROM Orders as o
INNER JOIN StanardTimes as st on o.ProductNum = st.ProductNum
INNER JOIN Inventory as i on i.ProductNum = st.ProductNum
Some sample data would be helpful to help design the queries.
In principal you would need to join the tables together to get the desired result.
You would join the productID on tblOrders to the ProductID on tblProducts. This will net you the name of the product etc.
This would be an INNER join, as every order has a product.
You would then join to tblSpareParts, also using the productID so that you could return the status of the spare parts for that product. This might be a LEFT JOIN instead of an INNER, but it depends on if you maintain a value of 0 for spare parts (e.g. Every product has a corresponding spare parts record), or if you only maintain a spare parts record for items which have spare parts.
Related
I am currently trying to design DB(mysql) structure for my project which is an online shop for wholesale company - I already created everything when it comes to products, it's multiple variants etc but I have problem with following which is price and historic data for multiple suppliers:
Please find below main assumptions for the project:
We are going to have several suppliers for products
Thanks to the above each product will have few different prices
We want to be able to have historic price data for each product with each supplier
Variant 1
At first I thought about adding 2 tables to my DB:
suppliers table: supplier_id, name
prices table: id, product_id, price_supplier1, price_supplier2, price_supplier3, timestamp
However in such example whenever we want to add another supplier we need to add row to the database (I am not a db expert but I guess that's not the best approach)
Variant 2
Another idea was just to have price table with following:
suppliers table: supplier_id, name
prices table: id, product_id, supplier_id, timestamp
However in this case if we have 5 suppliers we get 5 records created for 1 products every single day so let's imagine that we have only 1000 products and want to keep historic data for last 6 months - such table would grow very rapidly
So to summarize - which approach is better or maybe there is a different one that I could implement? Thanks a lot for any suggestions.
You should go with variant 2. It's best practice to avoid frequent table restructure, which you would have to do in variant 1 any time you add or remove a supplier (although MySQL is fairly fast at this in recent versions). Using a single column to identify the distinct supplier values is better. It also promotes query reuse when you don't have to worry about column values changing or being dropped altogether. Also, space shouldn't really be a concern. To give you an idea, if your prices table had 1,000,000 rows (6 months), it would be about 40-50M in size (assuming only a primary key index). MySQL also offers compression and partitioning to reduce storage as well, if that's really a concern.
I'm building a small inventory database in MS Access (2007), and I have one big dilemma: Should I store purchased (acquired) products/quantities in the same table as sold, with a field for transaction type, or should I separate them in two tables?
I'm working on second option now, but I'm stuck on querying these two tables.
tblProducts: ProductID (PK), ProductCode, ProductName
tblVendorsCustomers: VndCstID(PK), VndCstName, etc..(Vendors can also be Customers and vice-versa)
tblPurchase: PurchaseID(PK), PurchaseNumber(specific), VndCstID(FK), DatePurchased, DueDate
tblPurchaseDetails:PDetailsID(PK), PurchaseID(FK), ProductID(FK), QuantityPurchased, PricePurchased
tblSale: SaleID(PK), SaleNumber(specific), VndCstID(FK), DateSold, PayDate
tblSaleDetails: SDetailsID(PK), SaleID(FK), ProductID(FK), QuantitySold, PriceSold
Two tables (Purchase, Sale) are updating fine. Now, for example, when I want to show a report for a chosen Product, I need to pull data from these two tables, to see purchased quantity (along with Vendor name, date of purchase, and price) and sold quantity (with same set of data) and to calculate available quantity (at a given date). Maybe I'm missing something, but the only way to do this is create two select queries (for each of these tables), than union of these (to pull all transaction data), then a select query of that union, add an identifier field (for row from purchases and row from sales) and criteria for product selection..and I'm stuck on calculating available quantity..I'm guessing sum IIf, but not sure how to use it..
Sorry for such a long post...
Is this the right approach?
Any help or advice would be appreciated.
I have three tables: product, sales_order (where I sell products) and purchase_order (where I buy products). Now I can think of two ways of keeping the quantity of each product:
Have a column in the product table called quantity; when inserting into sales_order, I subtract the quantity; when inserting into purchase_order, I add the quantity
Instead of storing the quantity in the product table, I calculate the quantity from the sales_order and the purchase_order table each time I need to get the product table
I am wondering if the second approach is preferable to the first one? I like the second one more because it doesn't store any redundant data; however, I am not so sure if calculating the quantity every time is a bit too much calculation. I am wondering what is the convention and best practice here? Thank you!
I would use the first one. Add a column to the product table in the coding u code -x amount when order and you would then display this in the order table. You could right a script for when the products get to a certain amount it emails you and tells u to replenish stocks. However the second would also work and sql is very powerful so i wouldnt wprry about it being ro demanding as it will prbably work it out faster than we can lol
I prefer the first one because in-memory calculations are faster than issuing select statements to check the sales orders and purchase orders assuming that the number of times the quantity value is retrieved is significantly more than the number of times the quantity value is updated.
I've created a stock control database which contains two tables (actually more than two, but these are the two that are relevant to my question): Stock, and Receipts
I would like the link between the stock in the stock table,and the stock in the receipts table to be a little more clearer, this would be fine if a customer could only order one item of stock per receipt, as i'd simply have a StockID column and a Quantity column in the Recipts table, with the StockID column as an FK to the ID in the Stock table, however, the customer can make a receipt with any number of items of stock on it, which would mean i'd have to have a large number of columns in the Receipts table (i.e. StockID_1, Quantity_1, StockID_2, Quantity_2 etc.)
Is there a way around this (can you have like a dynamically expanding set of columns in MySQL) within MySQL, other than what i've done at the moment, which is to have an OrderContents column with the following structure (which isn't enforced by the database or anything) StockID1xQuantity,StockID2xQuantity and so on?
I would post an image of the DB structure, but I don't have enough repuation yet. My lecturer mentioned something about that it could be done, by normalising the database into 4th or 5th normal form?
I'd suggest having 3 tables:
Stock (StockID) + stock specific fields
Receipt (ReceiptID) + receipt specific fields.
StockReceipt (ReceiptID, StockID, Quantity) (could have a StockReceiptID, or use StockID+ReceiptID as Primary Key)
A solution including prices could look like:
Stock (StockID, Price)
PriceHistory (StockID, Price, Date) or (DateFrom, DateTo)
Receipt (ReceiptID, ReceiptDate)
StockReceipt (ReceiptID, StockID, Quantity)
That way you can calculate TotalStockReceiptPrice and TotalReceiptPrice for any receipt in the past.
I suspect this might be what you're looking for:
Stock (StockID, StockPrice)
Receipt (ReceiptID)
StockReceipt (ReceiptID, StockID, Quantity)
SELECT r.ReceiptID, SUM(s.StockPrice * sr.Quantity) AS ReceiptPrice
FROM Receipt r
INNER JOIN StockReceipt sr ON r.ReceiptID = sr.ReceiptID
INNER JOIN Stock s ON sr.StockID = s.StockID
GROUP BY r.ReceiptID
This is all very normalised (again, no idea to what normal form - 3rd?). However it only works if the StockPrice on the Stock record NEVER changes. As soon as it changes your ReceiptPrices would all reflect the new price instead of what the customer actually paid.
If the price can change, you'd need to either keep a price history table (ItemID, Price, DateTo, DateFrom) or record the StockPrice on the StockReceipt record (and then get rid of the JOIN to the Stock record in the above query and make it use sr.StockPrice instead of s.StockPrice)
To do the INSERT you posted below, you'd have to do:
INSERT INTO StockReceipts (ReceiptID, StockID, Quantity, TotalStockPrice)
SELECT 1, 99, 2, s.StockPrice
FROM Stock s
WHERE s.StockID = 99
However it's quite likely that whatever is issuing this receipt (and triggers the INSERT) already knows the price so could just insert the value.
No, relational databases do not allow dynamic columns. The definition of a relational table is that it has a header that name the columns, and every row has the same columns.
Your technique of repeating the groups of stock columns is a violation of First Normal Form, and it also has a lot of practical problems, for instance:
How do you know how many extra columns to create?
How do you search for a given value when you don't know which column it's in?
How do you enforce uniqueness?
The simplest solution is as #OGHaza described, store extra stock/quantity data on rows in another table. That way the problems above are solved.
You don't need to create extra columns, just extra rows, which is easy with INSERT.
You can search for a given value over one column to find it.
You can put constraints on the column.
If you really want to understand relational concepts, a nice book that is easy to read is: SQL and Relational Theory: How to Write Accurate SQL Code by C. J. Date.
There are also situations where you want to expand a table definition with dynamic columns that aren't repeating -- they're just new attributes. This is not relational, but it doesn't mean that we don't need some data modeling techniques to handle the scenario you describe.
For this type of problem, you might like to read my presentation Extensible Data Modeling with MySQL, for an overview of different solutions, and their pros and cons.
PS: Fourth and Fifth normal form have nothing to do with this scenario. Your lecturer obviously doesn't understand them.
I have a table with the following fields (for example);
id, reference, customerId.
Now, I often want to log an enquiry for a customer.. BUT, in some cases, I need to filter the enquiry based on the customers country... which is in the customer table..
id, Name, Country..for example
At the moment, my application shows 15 enquiries per page and I am SELECTing all enquiries, and for each one, checking the country field in customerTable based on the customerId to filter the country. I would also count the number of enquiries this way to find out the total number of enquiries and be able to display the page (Page 1 of 4).
As the database is growing, I am starting to notice a bit of lag, and I think my methodology is a bit flawed!
My first guess at how this should be done, is I can add the country to the enquiryTable. Problem solved, but does anyone else have a suggestion as to how this might be done? Because I don't like the idea of having to update each enquiry every time the country of a contact is changed.
Thanks in advance!
It looks to me like this data should be spread over 3 tables
customers
enquiries
countries
Then by using joins you can bring out the customer and country data and filter by either. Something like.....
SELECT
enquiries.enquiryid,
enquiries.enquiredetails,
customers.customerid,
customers.reference,
customers.countryid,
countries.name AS countryname
FROM
enquiries
INNER JOIN customers ON enquiries.customerid = customers.customerid
INNER JOIN countries ON customers.countryid = countries.countryid
WHERE countries.name='United Kingdom'
You should definitely be only touching the database once to do this.
Depending on how you are accessing your data you may be able to get a row count without issuing a second COUNT(*) query. You havent mentioned what programming language or data access strategy you have so difficult to be more helpful with the count. If you have no easy way of determining row count from within the data access layer of your code then you could use a stored procedure with an output parameter to give you the row count without making two round trips to the database. It all depends on your architecture, data access strategy and how close you are to your database.