Replace a column in another table in mysql with a condition - mysql

I want to replace tags rows in my database news table product where the product name is equal to the product name in another table product.
I want to copy the tags column from the products database to the product database tags must be in the correct row like the name column must match both tables.
I tried a query but it send me an error:
Table to copy = product
Table from copy products
Condition (name=name) or (slug=slug)
In both Table:
UPDATE product
set tags = (
select tags
FROM products
where product.name = products.name
);
It gives an error:
Subquery returns more than 1 row
It works with:
UPDATE product
set tags = (
select tags
FROM products
where product.id = products.id
);

What I have found to better understand and make sure you ultimately want in the final update, yet also make sure you are getting the records intended. Write the select first.
select
np.name,
np.tags NowTags,
op.tags OtherTags
from
NowProduct np
JOIN OtherProduct op
on np.Name = op.Name
Once you have this confirmed, just change the SELECT to an UPDATE. You can use the "alias" for the table being updated. I found its best to make sure your query is correct to see what records WILL be queried and what the before and what you WANT updated values should be. Once good, then apply update.
update np set
tags = op.tags
from
NowProduct np
JOIN OtherProduct op
on np.Name = op.Name

Related

MySQL error updating a table using join

I am trying to update a table in a mysql database, and am getting a syntax error. It is a MyISAM table if that matters.
Here is the sql
UPDATE product SET price=(price*1.0909)
JOIN product_to_category ON product.product_id = product_to_category.product_id
WHERE category_id =6
OR category_id =1
OR category_id =2
My goal is to get a list of products from 3 specific categories (information from the *product_to_category* table) and increase the price by about 10%. The price is contained in the product table.
From what I see in the documentation I can use join in the update statement, and I have done similar queries in the past.
This is a production website, which currently has about 40,000 products. If needed I can do a php script that will loop through the products and do it one by one, but it seems like I should be able to do it directly from mysql.
Your statement is a little bit messed up. SET follows after JOIN which is part of the UPDATE clause.
UPDATE product
JOIN product_to_category
ON product.product_id = product_to_category.product_id
SET price = price * 1.0909
WHERE category_id IN (1,2,6)

SQL code to change value of a field on one table based on value of a different field in a different table

I'm a complete novice at SQL so please be gentle...
I have a database of products. I would like to use SQL to move a batch of products to a different category, based on if a particular word is present in the products title, and also, only if the products quantity is zero.
The database includes 2 relevant tables:
1st table is products which has these 2 relevant columns: products_quantity and master_categories_id
2nd table is products_description and it has relevant column products_name (the title)
So, for an example, a product with the following title (stored in the column products name):
Archimede Seguso Murano Incalmo Millefiori Glass Bowl
I would like the SQL code to find this product (any any others that contain the word Archimede in the title), check if the stock quantity is 0, and if so, change the value of the column master_categories_id to 277 for those products.
The code I have so far come up with is:
UPDATE products
SET master_categories_id = '277'
WHERE products_quantity = '0' and products_name = 'Archimede';
However, this does not work as the column products_name is not in the products table. I have spent many hours searching for the correct method of doing this, with no luck, and would be eternally grateful for any help!
My website is built using zencart, and the above SQL was run using Zen Carts Admin "SQL Query Executor", but I can also run the SQL using phpMyAdmin if that helps. I am using MySQL version 5.
Sorry if I have left out anything obvious that you need to know, like I said I am a complete novice, but I will try to provide any other info you need. Thanks in advance!
Assuming you have a products id column in both tables that you can use to JOIN, you will need to JOIN the tables to do the UPDATE:
UPDATE products p
INNER JOIN products_description pd
on p.product_id = pd.product_id
SET p.master_categories_id = '277'
WHERE p.products_quantity = '0'
and pd.products_name = 'Archimede';
If you want to update any rows that contain Archimede, then you will have to use the LIKE operator in SQL:
UPDATE products p
INNER JOIN products_description pd
on p.product_id = pd.product_id
SET p.master_categories_id = '277'
WHERE p.products_quantity = '0'
and pd.products_name LIKE '%Archimede%';
The LIKE operator will find any rows that contain Archimede in the title.

Mysql join query issue

I currently have an issue with an SQL query. I have a product table which contains a colour_code field. I cannot alter the product table as it is taken in from an external source.
On the website a user can search a product by colour_code and return all the products available in this colour.
The task at hand is to have a different search term return a certain product which has a different colour code. For this, I added a new table called colour_code_alias which simply has a colour_code field which corresponds to the colour_code field in the product table and an alias field which would return this result. See table examples below.
**Product_tb**
id, colour_code
1, "ABC"
**colour_code_alias_td**
colour_code,alias
"ABC","XYZ"
So, if a user searches for XYZ, they should be returned product with the id of 1. If they search for "ABC" they should also be returned the product with the id of 1.
My problem is that the query is taking too long to execute as it isn't using an index. My simplified query is below:
Select * from product
left join colour_code_alias cca on cca.colour_code = product.colour_code
where (product.colour_code = 'XYZ' or cca.alias = "XYZ")
When I use the explain it shows its not using a key for this query.
When I remove the 'or cca.alias = "XYZ"' in the where clause, the colour_code index from the product table is being used.
I'm looking for help as to increase performance of such a query, how I should index this type of query or even should I rewrite it?
Any help is appreciated.
Thanks,
Martin.
just as a note as to what I've done.. I've removed the left join and added a select query into the where clause. The query looks like the following:
Select * from product
where (product.colour_code = 'XYZ' or product.colour_code = (select colour_code from colour_code_alias where alias = 'XYZ') );
you should have an index on product.colour_code and alias for sure.
another thought is to avoid the OR part entirely by populating the alias table with the original as well... something like:
'ABC','ABC'
that way you have one place to look.
EDIT:
one more thought - use numeric keys instead of strings - this will be more efficient also. (but may be difficult if you can't change the table)
You can try this query:
select *,
(select id from product where colour_code = cod.colour_code ) as id_prod
from
colour_code_alias cod
where (cod.colour_code = 'ABC' or cod.alias = 'XYZ')

MySQL DELETE with JOIN on condition

I have 3 tables; products, variants, and stock {simplified}
PRODUCTS
id
name
discontinued (ENUM: 0 or 1)
etc
VARIANTS
id
product_id
colour
size
STOCK
id
variant_id
branch_id
When the user selects to discontinue the PRODUCT I set the discontinued flag to 1. That's fine, but I want to delete the PRODUCT and VARIANTS records altogether if there is no STOCK record of the product. Obviously I can do this using a SELECT query first in PHP but I would like to do it in one mySQL query. This is what I have so far, but it is returning an error from mySQL:
$query = "DELETE FROM prod_lines,
JOIN variants ON variants.lineid = prod_lines.id
WHERE prod_lines.id = '$lineid' AND
(SELECT COUNT(id) FROM stock WHERE stock.variantid = variants.id) = 0";
Can anybody out there help me come up with the right solution? Maybe there is a better way that doesn't even involve a subquery?
Thanks in advance
I assume that the product_line table in your query is the PRODUCTS table you describe in the beginning of your post.
DELETE prod_lines.* -- you must specify which table you are deleting from, because there are several tables in the FROM clause
FROM prod_lines
JOIN variants ON variants.lineid = prod_lines.id
LEFT JOIN stock ON stock.variantid = variants.id
WHERE prod_lines.id = #lineid -- your "$lineid" variable here
AND stock.id IS NULL; -- selects only items with no match in the "stock" table
http://sqlfiddle.com/#!2/40a21
Try something like this,the downside is though you have to have two php variables here and also an nested query that you may not be ok with
DELETE FROM (select COUNT(id) countstock FROM stock s,variants v WHERE s.variantid = v.id and v.productid='$lineid') prod
where prod.countstock>1 and prod.productid='$lineid'

How can i update a table based on a count of another table while using LIKE statement

I know how to update one table's field from another table's count using t1.id=t2.id etc.. but i have somewhat typical issue. I have to use LIKE STATEMENT in WHERE clause.
This is something similar i wanted to do.
UPDATE `CATEGORIES`
SET `num_listings` = (SELECT COUNT(*)
FROM `LISTINGS`
WHERE `LISTINGS`.`CATEGORY` LIKE
ws_concat('', "%-", `CATEGORIES`.`ID`, "-%"));
(Example: I have CATEGORY stored as -25- in the LISTINGS table as a field name CATEGORY)
I understand that i cannot use ws_contact here but is there another way to achieve it?
Thanks in advance.
Unless there is a good reason for the category ID to be represented only by a part of a string in the listings table, the best way to handle such a structure of data is to add a category_id column to the LISTINGS table, and make sure that when adding or editing a listing this column is populated properly.
This would allow to simply JOIN the two tables ON categories.id = listings.category_id and makes much more sense. This would also give better performance by far.
If you do want to keep the DB structure as is, you can use a temporary table, with LIKE and CONCAT:
DROP TABLE IF EXISTS temp;
CREATE TABLE temp AS
SELECT categories.id, COUNT(*) AS c
FROM categories
JOIN listings ON listings.category LIKE CONCAT('%',categories.id,'%')
GROUP BY categories.id;
UPDATE categories, temp
SET categories.num_listings = temp.c
WHERE categories.id = temp.id;