Need to archive data on successful cart transaction using Update SQL JOIN - mysql

I need to archive a product when it has been bought in the storefront. I`m thinking about doing a SQL JOIN but not sure...
Is this the query I need to run?
UPDATE product
INNER JOIN cart on cart.product_id = product.id
SET product.archive = 1
cart
id (int)
product_id (int)
quantity (int)
product
id (int)
name (varchar 45)
price (decimal 10,2)
quantity (int)
image (varchar 255)
archive (tinyint) default 0

That seems like a situation where you'd you want to use a trigger. Everytime a new line is added in the Cart table, it should update product.archive to 1 (or any other changes to the Product table).
DELIMITER $$
CREATE TRIGGER tg
AFTER INSERT ON Cart
FOR EACH ROW
BEGIN
UPDATE Product
SET archive = 1
WHERE Product.id = NEW.product_id;
END $$
Please take into account that I'm new to MySQL and I'm not sure if this is the right way to do this.

The update query
Let's examine this query closely
UPDATE product
INNER JOIN cart on cart.product_id = product.id
SET product.archive = 1
What does this query do? It archives every single product that has been placed into at least one user's cart. Surely that's not what you want? Your cart table does not have a user id in it. HOw do you determine which item in the cart belong to which user? Please consider adding such a column to your table.
To archive or not to archive
Shouldn't a product be archived only when it's quantity reaches zero? but should it be archived at all? If you have an archive column in your table in each query you will need to have a clause that checks this flag
SELECT * FROM product WHERE archive = 1 /* or 0 */
But this archive column can take only one of two values and that makes an index on that column completely useless. So as your data grows, your queries will become slower and slower.

Related

What is the best way to set a list of data on the same table id?

I will try to walk you through the problem that I am facing so that you could understand how I got to this point.
This was my initial db:
The idea was to let one user update the value of a product. It was working fine though like this I can't record every update that the user has made because if that user updates the same product again it will just rewrite the last update and not write in the latest as intended. That was the case because the id's of user and product were matching on the two updates. So I tried to add another table just for the recording of updates like so:
Though the problem consists. Do I have to make another many to many relationship whose one end will be user_product or is there an more elegant way to resolve a problem like this?
you only need a "histiory"table that references
the productID and the changes made with timestamp and if more users are allowed to change the product also the userid
As Id you have an autoincrement
When you want to know the latest changes You select all rows for that productid and sort it by timestamp Or only the price
like
history_products
id
product_id
alcohol
amount
mass
name
picture
price
timecreated
And use a select like
SELECT price,timecreated FROM history_products WHERE product_id = 10000 ORDER by timecreated;
You can insert automatically by using a trigger
DELIMITER $$
CREATE TRIGGER afterupdateproduct
AFTER UPDATE
ON products FOR EACH ROW
BEGIN
INSERT INTO history_products (product_id,alcohol,amount,mass,name,picture, price,timecreated)
VALUES (OLD.alcohol,OLD.amount,OLD.mass,OLD.name,OLD.picture, OLD.price, Now());
END$$
DELIMITER ;

mysql function to update all rows in table A when table B updated

I have searched high and low for an answer but to no avail - it maybe because what I am asking is not possible ?
I thought a trigger calling a stored procedure might be the way forward ......
So, the question:
I have a table markup that holds just one record, an integer, lets say 10.
In table products each row has a number of columns including a price.
What I would like is for each row from table products to be updated with newPrice when the markup record changes, ie:
Calculate costPrice x markup = newPrice now update each row in table products
Hope that makes sense ?

Use value from a table in a second table

I have two tables called users and packages.
In users there is a column called "package" and in packages a column called "id".
What i'm trying to accomplish is, if the package id in the users table is changed to, lets say "1", then another field from the users table called "storage" should be changed to the corresponding "maxstorage" from the packages table... A little illustration here:
DATABASE:
Let's say Joe would like to upgrade to package number 2. Then his storage amount should be changed when his package is changed. It should pull the maxstorage from the packages table into the users table and then in the column "storage"...
How can i accomplish this?
It's pretty hard to explain for me, if anyone gets it then please edit for easier explanation.
What you want is not possible in a query (or at least, not simple). You have to move this logic to your code, e.g. you have a query which changes a row in the users table. In that query, also update storage.
Even better, drop the users.storage_id completely. Good databases don't repeat. you already have the data in the packages table, why copy it to the users?
SELECT users.name, packages.maxstorage
FROM users
LEFT JOIN packages ON (users.package_id = packages.id)
It can be that I didn't understand correctly your question, but what about this:
(pls make appropriate considerations on transactions to avoid conflicts).
CREATE TABLE P (ID INT, MAXSTORAGE INT);
CREATE TABLE U (USR_ID INT, PACKAGE_ID INT, STORAGE INT);
CREATE TRIGGER U_STORAGE_UPDATE BEFORE UPDATE ON U
FOR EACH ROW BEGIN
SET NEW.STORAGE = IF(NEW.PACKAGE_ID<>OLD.PACKAGE_ID , (SELECT MAXSTORAGE FROM P WHERE ID = NEW.PACKAGE_ID), NEW.STORAGE);
END;
INSERT INTO P VALUES (1,12345);
INSERT INTO P VALUES (2,54321);
INSERT INTO U VALUES (1,1,12000);
INSERT INTO U VALUES (2,2,60000);
SELECT * FROM U;
UPDATE U SET PACKAGE_ID=2 WHERE USR_ID=1;
SELECT * FROM U;
UPDATE U SET STORAGE=23
WHERE USR_ID=1;
SELECT * FROM U;
DROP TABLE P;
DROP TABLE U;
Output:
ante
USR_ID PACKAGE_ID STORAGE
1 1 1 12000
2 2 2 60000
post 1st update
USR_ID PACKAGE_ID STORAGE
1 1 2 54321
2 2 2 60000
post 2nd update
USR_ID PACKAGE_ID STORAGE
1 1 2 23
2 2 2 60000
Doesn't answer the question but might be useful to you:
The 'package' column in Users should have a foreign key restraint on 'id' in Packages. This ensures that all data in the 'package' column corresponds to a valid value in the Packages table. Otherwise you could enter some data into the 'package' column that doesn't have a value in the Packages table.

MYSQL copy from other table only if row does not exist

I have an existing MYSQL products table that has (amongst others) productID (autoinc) quantity productCode description
I have now been supplied with a spreadsheet that has all the products above + more new products.
I need to import only the new products that don't exist in the products table.
I am using sequel Pro on a mac. When I select the advanced section and select 'skip existing rows' it populates with productID = productID.
So I don't see a method to say if productCode = productCode skip this row.
I have created an new table productsAll that has all the new data in it and matched fields.
How do I loop through the productsAll table but only insert into the products table if the productCode does not exist.
Thanks..
You can use INSERT IGNORE
INSERT IGNORE INTO TABLE1 (SELECT * FROM TABLE2)

Updating a field with one from another database where a field matches in both

I'm trying to update all the prices in one database with the prices from another where the product code matches (which isn't the primary key), whilst leaving the other fields columns untouched.
INSERT INTO inventory
SELECT * FROM temporary_table
ON DUPLICATE KEY UPDATE price = VALUES(price)
This is just duplicating the whole product where the code matches
Thanks in advance
Try using replace instead of insert. select all the columns from inventory table except the one you want to update(price)
REPLACE INTO inventory
SELECT b.col1, b.col2......... a.price
FROM temporary_table a, inventory b
where a.product_code = b.product_code