MySQL: insert into multiple columns using selects from different tables - mysql

I have a products catalog that is imported directly to a website's database. Each product row lists its Category and Subcategory. After the products are imported, I run this SQL to add the distinct categories to the database (which are used for creating navigation URLs based on their ids):
INSERT INTO categories (name) SELECT Distinct category FROM catalog_products;
Now, I want to add the subcategories as well to it's own table, but with a reference to the ID of it's parent Category, which is what I'm having trouble with.
Example: the product "SDH 20" belongs to the Category "Diagnose" (has an id 5 on the 'categories' table) and to the subcategory "Hematology". The 'subcategories' table will then have to list Hematology as having a categoryID of 5, which is the ID of "Diagnose" on the category table. Here is the SQL I've attempted:
INSERT INTO subcategories (name, idCategory) SELECT Distinct subcategory FROM catalog_products UNION ALL SELECT id from category WHERE categories.name = (SELECT catalog_products.category FROM catalog_products);
But I get a "#1242 - Subquery returns more than 1 row" error.
Is it possible to populate the 'subcategories' table's name and idCategory with one SQL that reads the catalog_products rows? If so, what is wrong with my SQL?

You have to use 'IN' if your subselect Returns more than one row:
INSERT INTO subcategories (name, idCategory)
SELECT Distinct subcategory FROM catalog_products
UNION ALL SELECT id from category WHERE
categories.name in (SELECT catalog_products.category FROM catalog_products);
^^

Came up with one possible answer to my own question.
This was somewhat of a confusing query because it was dealing with 3 different tables at the same time, so I tried splitting into two simpler SQLs.
First, just like the categories table, I added all the distinct subcategory name's without their parent categoryID field.
INSERT INTO subcategories (name) SELECT Distinct subcategory FROM catalog_products;
Now, I update the existing subcategories with the categoryID of their parent category with this SQL, that also target's the products catalog:
UPDATE subcategories SET idCategory = (SELECT categories.id FROM categories,catalog_products WHERE subcategories.name IN (Select catalog_products.subcategory) AND categories.name IN (Select catalog_products.category));

As i understood you have two tables:
CATEGORIES: id|name
CATALOG_PRODUCTS: product|category|subcategory
UNION ALL gives you two different rows instead of two values that you expect. Try this:
INSERT INTO subcategories (NAME, idCategory)
SELECT cp.subcategory, c.categoryID FROM catalog_products AS cp
JOIN categories AS c ON cp.category=c.name
GROUP BY cp.name
You just need to join both tables on name and if you want to DISTINCT use GROUP BY
Hope that helps. Have not tested this SQL so correct it a bit if needed

Related

select names that is equal to the id of other tables - SQL

I have two tables products and categories. For products I have the ff fields:
id
pname
category_id
date
And for the cateogries id I have:
id
name
So using inner join I am trying to select all the names of categories that are equal to the category_id inside the products table.
Here's my take:
SELECT
c.name
FROM
categories AS c
INNER JOIN products AS p ON c.id = p.category_id
However this one did not work out and it's just sending me an empty array.
Any idea how can I do this? thanks!
If you just want category names, then exists or in is more appropriate than join:
SELECT c.name
FROM categories c
WHERE EXISTS (SELECT 1 FROM products p WHERE c.id = p.category_id);
You will not have to worry about eliminating duplicates, unless two categories have the same name.
This is also much more efficient than using SELECT DISTINCT on your query, especially if products has an index where category_id is the first key.

Proper SQL Query for Displaying the name instead of ID Reportico

I have 3 tables, Tickets, Category, and Sub Category. In Yii2 Reportico in order to generate reports you need to configure the SQL Query.
SELECT id, time_start, time_end, details, room_no, employee_id, category_id, sub_cat_id FROM tickets
This is my SQL Query for getting data in tickets table, instead of displaying the category_id and sub_cat_id. I want to display the category_name and sub_category, what is the proper sql syntax?
You can try something like this and see if you get the category name:
SELECT t.id, t.time_start, t.time_end, t.details, t.room_no, t.employee_id,
c.category_name , s.sub_category
FROM tickets as t inner join Category as c on t.category_id=c.id inner join
sub_cat as s on t.sub_cat_id=s.id and s.category_id=c.id
I'm not aware of field names you have in Category and Sub Category tables, but if it works for Category, try adding Sub Category table in a similar manner, or post the field list of both tables.

How to do mysql join to get result form 3 tables

I want to get category id and name from company category table which do not exists in company category cross table. For example the company with id 3 has already category 1 and category 2 and i want the sql result to get category 3
I tried following statement but not getting expected result
SELECT `wp_bmg_company_category`.id, `wp_bmg_company_category`.name
FROM `wp_bmg_company_category`
INNER JOIN `wp_bmg_company_category_cross`
ON `wp_bmg_company_category`.id != `wp_bmg_company_category_cross`.categoryid
if I understood correctly you search category which is now unused.
Select all company data with category ID (return only category ID)
Select all data from category where category id NOT IN (use 1. select data)
And if you find the only unused category for each company separately. Use something like this (ADD company_id for search each company separately, to search unused categories):
SELECT *
FROM category ca
WHERE category_id NOT IN
(SELECT category_id
FROM category c1
JOIN category_cross cc ON c1.id = cc.category_id
WHERE company_id = 1)
What you need is an outer join (left or right) that can retrieve all records from a table, regardless whether it is present in the other table. (You may use not in() or not exists() in place of the outer join).
The other technique you need is called Cartesian join, whereby you match all records from one table with all records from another table. In this case, match all records from the companies table with all records in the categories, to get the complete list of company - category combinations. Then subtract from this the list of categories you have.
select co.id, co.name, ca.id, ca.name
from (wp_bmg_company co join wp_bmg_company_category ca) --this creates the Cartesian join
left join wp_bmg_company_category_cross cr on co.id=cr.companyid and ca.id=cr.categoryid
where cr.id is null --only the non-matched pairs should remain

MYSQL select results from 3 tables with an array of ids

Ok, so I have 3 mysql tables where I need to extract data from. Anything to do with joins really gets me stuck!
Table 1 = products (productid, name)
Table 2 = category (categoryid, name)
Table 3 = categoryproduct (categoryid, productid) - my join table
I have an array of product ids which I need to get a random selection of products that fall into the same categories as these products.
The idea is that the results of the query will display a section in my cart of similar/related products that the customer may like
So something like
SELECT name etc FROM table1
WHERE table2.categoryid of results of the query = table3.categoryid of current products
ORDER BY RAND()
LIMIT 3
How do I write that??
Assuming you're using PHP, following method will fetch 10 related products from database.
$productids = array(1002,789,999,203,321);
$sql = '
SELECT * FROM
products p JOIN categoryproduct pc
ON p.productid = pc.productid
WHERE pc.categoryid IN(
SELECT DISTINCT(categoryid) FROM
products inner_p JOIN categoryproduct inner_pc
ON inner_p.productid = inner_pc.productid
WHERE inner_p.productid IN('.implode(',',$productids).')
)
ORDER BY RAND()
LIMIT 10';
If i have understood your problem correctly then this query may help. Here instead of subquery you can give comma separated string which contains categoryid of different products selected by the user.
select p.name
from products p,categoryproduct cp
where p.productid=cp.productid
and cp.categorid in(
select categoryid
from cartitems)
order by RAND()

MySQL join with 3 tables trick

I can't obtain the result I want, let me explain:
I have two tables :
CATEGORIES
PROJECTS
and between them another table which makes the link:
ASSIGNED_CAT with 2 columns: PROJECT_ID and CATEGORY_ID
In ASSIGNED_CAT I get the IDs of CATEGORIES and PROJECTS linked together.
Now I need to get the CATEGORIES which contains PROJECTS and if not don't show them.
Example:
If CATEGORY 1 have projects display the CATEGORY NAME and if not don't show.
Any idea to trick this? I've tried many SQL JOIN without success.
I guess you are missing the EXISTS clause.
The following query selects all categories, for which at least one row exists in the intersection table.
SELECT category_name
FROM categories c
WHERE EXISTS (
SELECT 1
FROM assigned_cat ac
WHERE ac.category_id = c.category_id
)