MYSQL select results from 3 tables with an array of ids - mysql

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()

Related

struggling with select with join and where clause

I'm running some SQL through phpmyadmin. I'm trying to do a query with 2 tables. The first xlsws_product has all the product info the second xlsws_category_assn contains two columns one with category id and the other with product id. The category names are in a third table but I don't need them for this.
What I am looking to do is select the rows from the product table that are in the categories with id 210, 218 and 370. This is what I tried so far:
SELECT *
FROM xlsws_product
JOIN xlsws_product_category_assn ON xlsws_product.id = xlsws_product_category_assn.product_id
WHERE
xlsws_product_category_assn.category_id = '210' OR '218' OR '370'`
The result for this gave me 24090 rows from a bunch of categories and there should only by a handful of rows in those categories. What's bizarre here is that there are 56474 rows in the product table so I'm not sure how the results are being filtered.
Just for the hell of it I tried limiting my query to just one category id with the following query:
SELECT *
FROM xlsws_product
JOIN xlsws_product_category_assn ON xlsws_product.id = xlsws_product_category_assn.product_id
WHERE xlsws_product_category_assn.category_id = '210'
This yielded zero rows...
I'm sure there is something simple I am missing but after spending a while searching for a solution I just can't figure it out. Thanks for the help.
If you need to find all the data which are in the category '210' OR '218' OR '370'
You can do as
SELECT * FROM
xlsws_product xp
JOIN xlsws_product_category_assn xpc ON xp.id = xpc.product_id
WHERE
xpc.category_id in (210,218,370)
If you need to find the products which have all the 3 given category you can do as
SELECT * FROM
xlsws_product xp
JOIN xlsws_product_category_assn xpc ON xp.id = xpc.product_id
WHERE
xpc.category_id in (210,218,370)
group by xp.id having count(*) = 3

mysql subquery returns more than 1 row error but that's what I want

I'm trying to do a select like this:
SELECT product.*, customers.*, product,id AS productid, (SELECT comment FROM notes WHERE product_id = productid) AS notes FROM products JOIN customers ON customers.product_id = product.id WHERE product.export = 0
It gives a error in the subquery for the notes, but I don't want to limit them to 1 I want to get unlimited notes for this product. Is this possible? And how? Or do I need to do a new query for each product to get the notes?
A query result can be seen as a grid of cells divided in rows and columns. Each of those cells can only contain one value. But what you can do, is combine all the values of the sub-query into a single value using an aggregation function like GROUP_CONCAT. GROUP_CONCAT will return all the notes as a single string of text.
SELECT product.*, customers.*, product,id AS productid,
(SELECT GROUP_CONCAT(comment) FROM notes WHERE product_id = productid) AS notes
FROM products JOIN customers ON customers.product_id = product.id
WHERE product.export = 0

mysql - Using Group By

I am trying to write a mysql query for an app I'm developing for android.
I have a database that has a bill_content table and a products table
I want to select top 10 most sold products.
This is a minimal version of what I have, but it's all I need to get an answer here.
bill_content table has the columns: id, id_product, quantity (id_product and quantity here can be duplicate because this table is larger, containing id_bill and other information)
products table has the columns: id, name
SELECT products.name AS Product,
bill_content.quantity AS Quantity
FROM bill_content, products
WHERE bill_content.id = products.id
ORDER BY bill_content.quantity DESC
LIMIT 10
Of course this returns a table of 2 rows containing all the products and their quantity in the bill_content table, but there are duplicates and I need to make sum of their quantity and display them as a single row.
Thank you in advance.
ANSWERED
This could be done using GROUP BY as Gordon Linoff said.
You want a group by. You should also learn to use proper explicit join syntax:
SELECT p.name AS Product,
SUM(bc.quantity) AS Quantity
FROM bill_content bc JOIN
products p
ON bc.id = p.id
GROUP BY p.name
ORDER BY SUM(bc.quantity) DESC
LIMIT 10;

Retrieve most popular products in a category sql statement

I'm trying to write an all encompassing SQL statement to retrieve the most popular items from my shop based on category ID. In english: For categoryID sort the most sold items
I've managed to query tblOrderContents and group + sort the results with most popular at the top:
SELECT productID, count(productID)
FROM tblOrderContents oc
GROUP BY productID
ORDER BY count(productID) DESC
which produces:
ID COUNT
16 419
12 52
34 38
33 33
But I'm struggling to figure out how to retrieve this for only a specific category. I'm thinking it will require a left join along the lines of but this doesn't work:
SELECT productID from tblProdCat
LEFT JOIN (SELECT STATEMENT DETAILED ABOVE)
WHERE categoryID = '7'
I hope this makes sense. I've been thinking about it so long i'm sure ive missed something obvious. Any advice would be great.
Thanks
Is productID in tblProdCat? If so, the following statement should work:
SELECT productID, count(productID)
FROM tblOrderContents oc
INNER JOIN tblProdCat pc ON oc.ProductId = pc.ProductId AND pc.CategoryId = '7'
GROUP BY productID
ORDER BY count(productID) DESC
Explanation: This inner join gives back only rows where the criteria (categoryID = '7' and matching productId's) is met. If a row does not satisfy this criteria, in either table, the row will not be returned.

Custom format mysql query and multiple values in one column

Forgive me if I get some terms wrong, still trying to learn advanced mySql queries. I am trying to export data from a ecommerce platform, and some of the data I need is in lookup tables, the issue is the one lookup table I have can have more than 1 value associated, and the system I need to get the data into requires a specific format for that column.
I am using zen cart as my source if that helps, and below is the query.
Select zp.products_id as id, zpd.products_name as name, products_price_w as cost, products_price as price, zp.products_date_added as date_created, zp.products_image as thumbnail
FROM `zen_products` as zp
LEFT JOIN `zen_products_description` as zpd ON zp.products_id = zpd.products_id
WHERE zp.products_status = 1
ORDER BY zp.products_id ASC;
What I need is theres a look up table that tells me what categories belong to each product, I know it's going to be another join, but I need it so if more than 1 category belongs to a product to put it in the same column, and join them with a # symbol, and its not the id's of the category, its the path, so I need to look up the category ID to another table to get the path.
So "category1/subcategory#category2" for example..
Thanks for any guidance.
EDIT: I still need to get the results merged as I am getting double the results I want, but I see a record for each category it's in with this..
Select zp.products_id as id, zpd.products_name as name, zcd.categories_name as categories, products_price_w as cost, products_price as price, zp.products_date_added as date_created, zp.products_image as thumbnail
FROM `zen_products` as zp
INNER JOIN `zen_products_description` as zpd ON zp.products_id = zpd.products_id
INNER JOIN `zen_products_to_categories`as zptc ON zp.products_id = zptc.products_id
INNER JOIN `zen_categories_description` as zcd on zptc.categories_id = zcd.categories_id
WHERE zp.products_status = 1
ORDER BY zp.products_id ASC;
What you are looking for is group_concat(). I think it would be something like this:
Select zp.products_id as id, zpd.products_name as name,
group_concat(zcd.categories_name separator '#') as categories,
products_price_w as cost, products_price as price,
zp.products_date_added as date_created, zp.products_image as thumbnail
FROM `zen_products` as zp
INNER JOIN `zen_products_description` as zpd ON zp.products_id = zpd.products_id
INNER JOIN `zen_products_to_categories`as zptc ON zp.products_id = zptc.products_id
INNER JOIN `zen_categories_description` as zcd on zptc.categories_id = zcd.categories_id
WHERE zp.products_status = 1
group by zp.products_id
ORDER BY zp.products_id ASC;