I have two tables. Products and products-sub. I want to show all the available colors for each product and a picture for that too.
So, my product table contains:
id,name,description
My product-sub table contains:
id, parentID, color, pic
I want to select all the colors and the pictures of one product and show it on the page. But I don’t want to show all the products on the same page.
select p.name, s.color, s.pic, p.id
from products-sub s
inner join products as p on p.id = s.parentID
This is my current query, and I want 50 unique s.parentID's.
One solution is to join on the parent table using a subquery with a LIMIT, e.g.
... JOIN (SELECT * FROM products LIMIT 50) p ...
If you want 50 products, then use a subquery:
select p.name, s.color, s.pic, p.id
from products_sub s inner join
(select p.*
from products p
limit 50
) p
on p.id = s.parentID;
This assumes, of course, that all the products have at least one sub.
Related
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.
I'm trying to create a list of my products. I got a join between two tables, products and products_photos.
I got X products which have one register on the products photos. The problem comes when I got two register on the product photos table which have the same id_product. Then, the results show 2 times the same product with the different photo. I want to show only the first one, not two times the same product.
SELECT DISTINCT p.*, photo.url_little
FROM ".Constants::$PRODUCTS_TABLE." as p
LEFT JOIN ".Constants::$PHOTOS_PRODUCTS_TABLE." as photo ON p.id=photo.id_product
WHERE p.id_client = ?
Probably I'm doing a bad use of the command distinct, but I don't know how to resolve this.
If you only want to show one, use a correlated subquery:
select p.*,
(select ph.url_little
from ".Constants::$PHOTOS_PRODUCTS_TABLE." ph
where p.id = ph.id_product
order by ph.id asc
limit 1
) as url_little
from ".Constants::$PRODUCTS_TABLE." as p
where p.id_client = ?;
if you use DISCINCT p.* then you obtain all the rows because you select also the row di (and this is unque)
try the same query but only with the column you need
SELECT DISTINCT p.column_i_need1, photo.url_little
FROM ".Constants::$PRODUCTS_TABLE." as p
LEFT JOIN ".Constants::$PHOTOS_PRODUCTS_TABLE." as photo
ON p.id = photo.id_product WHERE p.id_client = ?
I'm having a problem with a sql query to do the following:
I need to select all products from products table and for each product i need to join a main image (all columns) from images table. Product images table contains image-product relations and a column sortWeight. Main image is the one with the smallest sortWeight.
To get the main product image, i'd do this:
SELECT * FROM images WHERE product=SOME_PRODUCT ORDER BY sortWeight ASC LIMIT 1;
To get all products:
SELECT * FROM products;
Now i need to join these two somehow, but the problem is i don't know how to bypass a limitation in the following:
SELECT P.* FROM products AS P
LEFT JOIN
(SELECT * FROM images AS I WHERE I.product=P.id ORDER BY sortWeight ASC LIMIT 1) AS I1
The problem is MySQL does not know what P.id is inside the subquery. I've also tried it like this:
SELECT P.* FROM products AS P
LEFT JOIN
(SELECT * FROM images AS I WHERE ORDER BY sortWeight ASC LIMIT 1) AS I1 ON (I1.product = P.id)
but i don't think this gives an accurate result since there's a limit in subquery and it may select the image from another product with smaller sortWeight.
Can anyone help me rewrite this? Thank you.
Try to join it to subquery that returns images with smallest (min) sortWeight for each product.
This returns smallest sortWeight for each product:
select product, min(sortWeight) as sortWeight
from images
group by product
this is combined version:
SELECT P.*, i.*
FROM products AS P
left join images as i on p.id = i.product
LEFT JOIN (
select product, min(sortWeight) as sortWeight
from images
group by product
) t on t.product = i.product and i.sortWeight = t.sortWeight
I'd like to be able to return a thumbnail (first image of a set) with my product data - what is the best way to accomplish this (performance)?
I have the following tables:
products (product data)
products_images (relation between products and images)
images (image data)
So for every product, it'd return the first image of a set associated with that product.
Two things:
I'm trying to get the first image but the order depends on an 'order'
field.
If no image found just return null for image data but still
get product.
I'm thinking of doing a subquery since I don't know how to about ordering and limiting image results in a join.
What do you suggest?
Edit:
The image order field is present in the products_images table. That table has the following fields (product_id, image_id, order)
SELECT
p.*
, i.thumbnail
FROM
products AS p
LEFT JOIN
images AS i
ON i.image_id =
( SELECT image_id
FROM products_images AS pi
WHERE pi.product_id = p.product_id
ORDER BY `order` ASC --- or DESC
LIMIT 1
)
An index on (product_id, order, image_id) in table products_images would be useful for the subquery to run faster.
This should give you the first image by the order column in the product_images table:
SELECT *
FROM products p
LEFT JOIN (
SELECT pi.product_id, i.*
FROM images i
INNER JOIN (
SELECT product_id, image_id
FROM products_images pi
ORDER BY `order`
) pi ON i.image_id = i.id
GROUP BY product_id
) i ON i.product_id = p.id
SELECT *
FROM
productinfo as p ,
category as c
WHERE
c.id IN (p.category) AND
p.pid='T3'
WHERE p.category will return (1,2,3,4,5) from product info table which the id of the category.
Now i need category name used for T3 [product Id] ,but i am getting only the first category name.
Your base query is the following
SELECT * FROM productinfo as p WHERE p.pid = 'T3';
Now you need to pull in categories, per product. This is a many to one relationship, so you need a LEFT JOIN.
SELECT * FROM productinfo as p
LEFT JOIN category as c ON c.id = p.category
WHERE p.id = 'T3'
You need to learn the different types of joins and how they are used. Whenever I see someone use 'FROM table1, table2' 90% of the times it means they don't understand joins and they need a LEFT JOIN instead.
Edit based on your comment
Your datamodel is flawed. Since a product can contain multiple categories, this is really a many-to-many relationship. You should create a product_category table that connects product id's with category id's.