inserting data into a table that has a many to many relationship - mysql

I am working on an assignment and need your help with the following in SQL database:-
I have 3 tables
Product
LintItem
Invoice
LineItem is a bride table and I need to insert data into LineItem but it requires ProductID and InvoiceNumber.
In my case the Invoice table is emppty and it will be filled from the data that LineItem table passes.
The problem is how can I create an invoice before having the data from the lineItem table?
I am using these table for online shopping cart.
It's really hard for me to explain this problem. Hope you understand it, Thanks!

It sounds like you have a foreign key constraint forcing the existence of a Invoice record prior to inserting your line item records. It is hard to say exactly, based on the phrasing of your question but could be something like.
--Table variable to hold line items
DECLARE #lineItems TABLE
(
InvoiceNumber INT,
Quantity INT
)
INSERT INTO #lineitems VALUES(1,1)
INSERT INTO #lineitems VALUES(1,2)
--ADD INVOICE RECORD FIRST AND SUM Quantities etc....
INSERT INTO Invoice
SELECT InvoiceNumber,SUM(Quantity)
FROM #lineItems
GROUP BY InvoiceNumber
--NOW YOU CAN ADD LINE ITEMS
INSERT INTO LineItems SELECT * FROM #lineItems
This is a pattern you could use if that was your goal.
If you are wanting to insert these LineItems on the fly as the user is clicking Add from the webpage. I wouldn't use your LineItem SQL table for caching this way. Without knowing anything about your application it is hard to say but you really should be caching this data in the HTTP session or in the client as (array,json, local storage etc..). If you were to choose to do this as an SQL table just make a new LineItem without the constraints and then similarly per above you can use that table to insert into your LineItem table.

Related

Performance of Update query compared To Delete - Insert

I have two tables : Shop and Product
Table Shop
(id INT AUTO_INCREMENT,
shop_id INT,
PRIMARY KEY(id)
);
Table Product
(
product_id INT AUTO_INCREMENT,
p_name VARCHAR(100),
p_price INT,
shop_id INT,
PRIMARY KEY(product_id),
FOREIGN KEY(shop_id) REFERENCES Shop(id)
);
On a server using Node and mysql2 package for queries.
On a client side, I'm displaying all Products that are related to specific Shop in a table.
User can change Products, and when he is pressing Save, requests are being made, sending new data, and storing her.
User can either change existing Products, or add new ones.
But i have concerns, how it will behave with a relatively big amount of products per one shop. Let's say there are 1000 of them.
The data that was inserted - marked with the flag saved_in_db=false.
Existing data, that was changed - changed=true.
Considered a few approaches :
On a server, filtering array of records received from a client, INSERT into db newly created, that are not stored yet.
But to UPDATE existing Products, i need to create a bunch of UPDATE Products SET p_name=val_1 WHERE id = ? queries, and execute them at once.
To take all Products with the specified Shop_id, DELETE them, and INSERT a new bulk of data. Not making separation between already existing records, or changed.
In this approach, i see two cons.
First - sending constant amount of data from client to server.
Second - running out of ids in DB. Because if there are 10 shops, with 1000 Products in each, and every user frequently updates records, every update, even if one new record was added, or changed, will increment id by around 1000.
Is it the only way, to update a certain amount of records in DB, executing a bunch of UPDATE queries one after another?
You could INSERT...ON DUPLICATE KEY UPDATE.
INSERT INTO Products (product_id, p_name)
VALUES (123, 'newname1'), (456, 'newname2'), (789, 'newname3'), ...more...
ON DUPLICATE KEY UPDATE p_name = VALUES(p_name);
This does not change the primary key values, it only updates the columns you tell it to.
You must include the product id's in the INSERT VALUES, because that's how it detects that you're inserting a row that already exists in the table.

Multiple vote options storing in MySQL table

I have a poll which has an undefined number of options (it can have only 2 options, but it can also have 10 or 20 or more options to choose from). I need to store the current vote count in MySQL table. I can't think of a centralized way of storing them except:
Create a field vote_count and store a serialized array of voting options mapped to counts.
When new vote data comes in this field is read, unserialized, appropriate values are incremented, then field is written to. This needs 2 queries and there might be 5 or more votes incoming per second.
So I need a way to store voting counts for an unknown number of voting options and be able to quickly access it (I need up to date counts for every option displayed on the voting page) and quickly update it (when new votes come in). It has to be within MySQL table. There is no "upper" limit for the number of voting options.
The normative pattern for handling multi-valued attributes, or repeating values, is to add a second table.
Consider a purchase order that can have more than one line item on it. We represent the line items in a child table, with a foreign key to the parent in the purchase order table:
CREATE TABLE `purchase_order` (id int not null, foo varchar(200), ... );
CREATE TABLE `line_item` (id int not null, order_id int not null, ... );
ALTER TABLE `line_item` ADD FOREIGN KEY (order_id) REFERENCES order(id) ;
INSERT INTO purchase_order (id, foo) VALUES (101, 'bar');
INSERT INTO purchase_order (id, order_id) VALUES (783, 101);
INSERT INTO purchase_order (id, order_id) VALUES (784, 101);
INSERT INTO purchase_order (id, order_id) VALUES (785, 101);
We can get a count of the line items associated with a purchase order, like this:
SELECT COUNT(1)
FROM line_item
WHERE order_id = 101;
Or, we can get a count of line items for every purchase order, like this:
SELECT o.id, COUNT(l.id) AS count_line_itesm
FROM purchase_order o
LEFT
JOIN line_item l
ON l.order_id = o.id
GROUP BY o.id
In your case, what are the entities you need to represent (person, place, thing, concept or event; which can be uniquely identified and you need to store information about.
I'm having difficulty conceptualizing what entities it is you are need to represent.
poll -
poll_question - a single question on a given poll
poll_question_answer - a possible answer to a question to a given poll question
voter -
ballot - associated with one voter and one poll (?)
vote - the answer given to a particular poll question
Good database design comes from an understanding of the entities and the relationships, and developing a suitable model.
Can't you just have one table of questions, and another table of possible answers (multiple rows per question, as many as you want). Then either store the counts on the table of answers, or (better) have another table of actual entered answers (this way you can log the details of the person doing the answers, and easily use SUM / COUNT to work out how many votes each option has).

Foreign Key reference in mySQL

In mySQL if I created two tables and on table contains a foreign key referenced to the other table. I have entered data in the other table and for the defined foreign key in that as well. Is there any way for the foreign key to automatically update in the second table without having to type in the entire data?
For example I have a customer table which has 2 fields- customerID and customerName. Another table is say a invoice table which has 3 fields- invoiceID, cost and customerID, where customerID is foreign key. So if I enter data in customer table and invoice table as the number of customers are very large I do not want to keep on entering the customerID in the invoice table. As customerID is a foreign key in the other table, how do I make it automatically reference it from customer table?
You can automatically add a predefined number, like 1, but that will assign all invoices to customer#1.
On the other hand, you can add customers automatically while adding invoices. For that, you need to control the customerID and if a customer with the given ID is not present, insert a new customer to the customer table with empty name. After that, you still need to enter names for those customers, but not by one and that would get things (maybe) easier.
I think you have a misleading idea here. I strongly suggest reading a book or seeing a tutorial online or examining an example project's database tables.
If you have the customer name in invoice data and customer data already populated, you could do
INSERT INTO tbl_invoice (invoiceData, invoiceData2, customerID)
SELECT 'value1', 'value2', customer.customerID
FROM tbl_customer customer
WHERE customer.customerName = 'customer name'
So you wouldn't need to deal with customer ids directly.
There is no automatic feature in MySQL to do exactly this. A trigger could be used for it if needed.

MySQL - insert into with foreign key index

Here is the scenario:
I have 2 tables and 2 temporary tables. Before I insert user data to the official tables, I insert them to a temp table to let them do the checks. There is a company table with company info, and a contact table that has contact info. The contact table has a field called company_id which is a foreign key index for the company table.
Temp tables are set up the same way.
I want to do something like: INSERT INTO company () SELECT * FROM temp_company; and INSERT INTO contact () SELECT * FROM temp_contact
My question is, how do I transfer the foreign key from the temp_company to the newly inserted id on the company table using a statement like this? Is there a way to do it?
Currently I am:
grabbing the temp rows
going one by one and inserting them
grabbing the last insert id
then inserting the contacts afterwards with the new last insert id
I just don't know if that is the most efficient way. Thanks!
if you have the same number of columns in both tables and then you should just be able to use the syntax you have there? Just take out the (). Just make sure there aren't any duplicate primary keys:
INSERT INTO company SELECT * FROM temp_company;
INSERT INTO contact SELECT * FROM temp_contact;
You can also specifically specify the columns that get inserted, this way you can specify exactly which column you insert as the new ID.
INSERT INTO company (`ID`,`col_1`,...,`last_col`) SELECT `foreign_key_col`,`col_1`,...,`last_col` FROM temp_company;
INSERT INTO contact (`ID`,`col_1`,...,`last_col`) SELECT `foreign_key_col`,`col_1`,...,`last_col` FROM temp_contact;
Just make sure you are selecting the right # of columns.

SQL: flavours of INSERT INTO

(MySQL) I am trying to migrate a "subscription" table into 3 new tables: "product", "subscription", "actual" where "actual" is the name of the actual product, say, newsletter. The subscription has a FK reference to product and the actual has FK reference into subscription.
I know the INSERT INTO SELECT statement can copy data probably from many table to one; is there a statement to do the opposite, one to many tables for my case?
I'm not aware of an SQL statement that will do what you want. Just do several INSERT INTO SELECTs one after the other. It may be faster to do them one at a time anyway.
I think you can use three seperate insert into select statements. First you convert the product table, then the subscription where you can use an embedded select to find the id in the product table:
insert into subscription (some_column, FK_id,...)
select something, (select id from product where <your where clause>),...
and finally convert the actual table using an embedded select to get the id from the subscription table.