join and group the joins in array - mysql

products
products_prop
specification
now i want to get the product and in cell i want to get array with all products_prop and the name from specification
if i do like this
SELECT *
FROM `products`
INNER JOIN `product_prop`
ON products.id = product_prop.product_id
INNER JOIN `specification`
ON product_prop.specification_id = specification.id
GROUP BY products.name
what i need to do for get 1 row of product and the all product_prop in array with the name of specification?

Related

Sql subquery that converts a column into a list

Is it possible to write a subquery that will return the result in a string.
Code:
SELECT service_provider.service_provider_id,f_name,l_name,email,phone,service_provider.timestamp,categories.category
FROM service_provider
INNER JOIN service ON
service.service_provider_id = service_provider.service_provider_id
INNER JOIN categories ON
categories.category_id = service.category_id
where service_provider.status = 'active'
I have tried above query it return results in separate lines, what I want is when the value in category column is different it should add up in column as a list.
Use GROUP_CONCAT() to concatenate all the category names.
SELECT service_provider.service_provider_id,f_name,l_name,email,phone,service_provider.timestamp,GROUP_CONCAT(c.category) AS categories
FROM service_provider
INNER JOIN service ON
service.service_provider_id = service_provider.service_provider_id
INNER JOIN categories ON
categories.category_id = service.category_id
where service_provider.status = 'active'
GROUP BY service_provider.service_provider_id

Mysql (doctrine) - count inner join having count > X

I have SQL to count products with specific properties. I am using it in the products filter. SQL is very long, but here is the primary part:
SELECT COUNT(products.id) as products_count, property_items.description, property_items.id as id
FROM property_items
INNER JOIN product_properties ON property_items.id = product_properties.property_item_id
INNER JOIN products ON product_properties.product_id
INNER JOIN product_properties pp ON products.id = pp.product_id AND (pp.property_item_id IN ($ids))
GROUP BY property_items.id
HAVING COUNT(pp.id) >= $countIds
This works perfectly when I have only the one element in $ids, but when i choose one more, the result is bad. It looks like the sql returns count of all products with any property from $ids, but I need to count only products that contains all properties.
First get all available properties. On each property join products that contains this property and go back to all properties of this product to check, if product contains already checked properties too. Or it is bad idea? I need to keep primary table (FROM table) as property_items.
I need to get result in this format:
=============================
id|description|products_count
=============================
1 |lorem ipsum|10
-----------------------------
2 |dolore sit |2
Thanks for any idea.
Try to use SELECT COUNT (DISTINCT products.id) as cnt
You can get the product ids that have all the properties by doing:
SELECT pp.property_id
FROM property_items pi INNER JOIN
product_properties pp
ON pi.id = pp.property_item_id INNER JOIN
products p
ON pp.product_id = p.id
WHERE pp.property_item_id IN ($ids)
GROUP BY pp.property_id
HAVING COUNT(DISTINCT pp.property_item_id) = $countIds -- has all of them
Note that I rationalized the joins. I think your simplification of the query wasn't quite right. I also added table aliases, so the query is easier to write and to read.
If you want the count of such products, use a subquery:
SELECT COUNT(*)
FROM (SELECT pp.property_id
FROM property_items pi INNER JOIN
product_properties pp
ON pi.id = pp.property_item_id INNER JOIN
products p
ON pp.product_id = p.id
WHERE find_in_set(pp.property_item_id, $ids)
GROUP BY pp.property_id
HAVING COUNT(DISTINCT pp.property_item_id) = $countIds -- has all of them
) ;
Your problem is probably because of this line:
WHERE pp.property_item_id IN ($ids)
If you are passing $ids as a comma-separated string, then your query will not work. Note the replacement above.

mysql join on product category multiple relation query

I have three tables as below, each product may belong to multiple categories.
PRODUCT TABLE AS P
1. ID
2. NAME
CATEGORY TABLE AS C
1. ID
2. NAME
RELATION TABLE AS R
1. ID
2. P_ID
3. C_ID
Now I want to get a list of all products in product table, and with their belonging category name display as well.
How do I write this query?
I can get the category ids pulled from the same query, but don't know how to get all the name pulled as well. Here's what I tried.
select p.*,y.*
from p
left join (select p_id,group_concat(c_id) as category_ids
from relation group by p_id) as y on p.id=y.p_id
Do both JOIN operations (to the relation table, and from there to the table containing the category names) and feed the result to your aggregation function (GROUP_CONCAT)
SELECT P.Name, GROUP_CONCAT(DISTINCT C.Name ORDER BY C.Name SEPARATOR '|') categories
FROM Product P
LEFT JOIN Relation R ON P.ID = R.P_ID
LEFT JOIN Category C ON R.C_ID = C.ID
GROUP BY P.ID, P.Name
This will give you one row per product with the categories separated by |.
This uses LEFT JOIN operations so it won't suppress products that have no categories.
Select P.Name, C.Name
From RELATION R Inner Join PRODUCT P
On R.P_ID=P.Id
Inner Join Category C
On C.Id=R.C_ID
This query will get you all the products, with their corresponding category.
I want to give you a small explanation about the difference between Inner Join and Left Join.
If we take as an example 2 tables :
TA(idA, description) and TB(idB, idA, description).
Select TA.description, TB.description
From TA Inner Join TB On TA.IdA = TB.IdA
will get only the rows in TA, that have a corresponding one in TB.
On the other side,
Select TA.description, TB.description
From TA Left Join TB On TA.IdA = TB.IdA
will get all the rows of TA and if the row in TA doesn't have a corresponding one in TB, TB.description for this row will be NULL.
Hope this helps!

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

MySQL left join multiple column pairs

Given the following table (products_filter):
How can I do a SELECT ... FROM products LEFT JOIN products_filter ... in such a way that it only returns products which have ALL the specified (filter_id,filter_value) pairs.
Example: for (filter_id, filter_value) = (1,1),(3,0) it should only return the product with id 90001, because it matches both values.
If the specified filter pairs is restricted to a deifnite number the the following query should work.
Select a. Product_id
From products a
Left outer join
(Select product_id,filter_id,filter_value,count(*)
From product_filter
Where filter_id in (1,1) and filter_value in(3,0)
Group by product_id,filter_id,filter_value
Having count(*)=2)b
On(a.product_id=b.product_id)
As you only said you wanted the PRODUCTS values having the desired filter attributes... I've limited results to just product.*
The below query uses an inline view with the count of distinct filters by product ID. The outer where clause then uses the distinct count (in case duplicate filters could exist for a product) of the filter_IDs.
The # in the where clause should always match the number of where clause paired sets in the inline view.
Your sample data indicated that the paired sets could be a subset of all filters. so this ensures each filter pair (or more) exists for the desired product.
SELECT p.*
FROM products p
LEFT JOIN (SELECT product_ID, count(Distinct filter_ID) cnt
FROM products_Filter
WHERE (Filter_ID = 1 and filter_value = 1)
or (Filter_ID = 3 and filter_value = 0)
GROUP BY Product_ID) pf
on P.Product_ID = PF.Product_ID
WHERE pf.cnt = 2