sql join distinct php - mysql

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 = ?

Related

MySQL JOIN tables with COUNT values

I have the following tables in my database.I only listed the important columns which can be used for joining.
I need to get the following output
Currently I'm using two seperate queries for each COUNT value
For assigned licenses
select
products.id,products.name,COUNT(assigned_licenses.id)
from
deployment_users
inner join
assigned_licenses
on
deployment_users.id = assigned_licenses.deployment_user_id
inner join
products
on
assigned_licenses.id = products.id
and
deployment_users.customer_id = 10
group by
assigned_licenses.id
;
For total licenses
select
products.id,products.name,COUNT(total_licenses.id)
from
customers
inner join
total_licenses
on
customers.iccode = licenses.iccode
inner join
products
on
total_licenses.id = products.id
and
customers.id = 10
group by
total_licenses.id
;
Since there are more than a 1,000 products that need to be listed,I want to combine them into a single query.How can I do that?
Your specification leaves some room for interpretation (e.g. can a user have assigned licenses without total licenses? if yes my query will fail.) but I would go with this.
SELECT
products.id,
products.name,
Count(Distinct total_licenses.id) As CountTotalLicenses,
Count(Distinct assigned_liceses.deployment_users_id) As CountAssignedLicenses
FROM products
LEFT JOIN total_licenses ON total_licenses.products_id = products.id
LEFT JOIN customers ON customers.iccode = total_licenses.customers_iccode
LEFT JOIN assigned_licenses ON assigned_liceses.total_licenses_id = total_licenses.id
WHERE
customers.id = 10
GROUP BY
products.id,
products.name
For the future it would be awesome if you could paste code as code and not as an image. People cannot simple copy paste snippets of your code and have to type everything again...
Try joining Both of your query
SELECT * FROM (
(First Query) as assigned_licn
INNER JOIN
(Second Query) as total_licn
USING (id)
);

Select limit on foreign key in MySQL

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.

Select distinct returning indistinct rows

Select distinct is returning indistinct rows. Why?
I want to return distinct shops.
Here is my sql statement:
SELECT
DISTINCT s.*, p.p_id
FROM
shop s
INNER JOIN product_shop ps on s.s_id = ps.s_id
INNER JOIN product p ON p.p_id = ps.p_id
WHERE
s.country = 'new zealand'
Here is the result:
The product (p.p_id) needs to not be distinct, as I want to return a list of shops that have a specific product. But the Shop needs to be distinct.
What am I doing wrong?
Returned rows are distinct. Distinct is applied to all returned row, not to single column. Yes, p_id is same for two rows. But if you compare all columns, there are differences between them.
If you want distinct shops - don't include in select columns from other tables, because it can cause duplicates as in your example.
Simply don't include p.p_id within your selection.
I.e.
SELECT DISTINCT
s.*
FROM shop s
....
Well, If you will look at your entire output, you can see the p_id(the last column) is different for each row. Distinct applies to the entire record, not just one column.
You can either drop the p_id from your select, or use group by and decide which one of the p_id you want, perhaps max? :
SELECT
s.*, max(p.p_id)
FROM
shop s
INNER JOIN product_shop ps on s.s_id = ps.s_id
INNER JOIN product p ON p.p_id = ps.p_id
WHERE
s.country = 'new zealand'
GROUP BY s.id

how to make a query that will get all products with its comments

I have two tables; one for products and the other for products comments. I need a query that can bring me all the products with their comments connected without duplicate results from the products table.
The problem is that when I use this query:
SELECT * FROM `food_products`
INNER JOIN `comment`
ON food_products.product_id = comment.product_id
It returns duplicates from the product table rows.
You probably want to concatenate the comments together. Try this:
select fp.*,
group_concat(coalesce(c.comment) seperator '!!!')
from food_products fp left outer join
comments c
on fp.product_id = comment.product_id
group by fp.product_id
This separates the comments with a "!!!". You can choose any separator you want; the default is a comma.

join one row from another table in mysql

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