Sql subquery that converts a column into a list - mysql

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

Related

join and group the joins in array

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?

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.

Left outer join with select where value in right table does not return all rows from left

I have a polymoprhic relationship table "likes" in which I store likes for the tables "lists", "articles", "comments".
The structure of the table is as follows:
id
content_id
content_type
I am trying to select all my lists with their like counts:
SELECT lists.*, COUNT(DISTINCT likes.id) AS likes FROM lists
LEFT OUTER JOIN likes ON (lists.id = likes.content_id)
WHERE likes.content_type = 'list'
GROUP BY lists.id
However, it only returns results from the list table where there are likes in the likes table.
Thank you for your help!
if you need left join you must inclue the where condition in on clause otherwise i used as inner join
SELECT lists.*, COUNT(DISTINCT likes.id) AS likes
FROM lists
LEFT OUTER JOINlikes ON
(lists.id = likes.content_id
AND likes.content_type = 'list')
GROUP BY lists.id

SQL Join involving 3 tables, how to?

SQL newbie here.
So we have 3 tables:
categories(cat_id,name);
products(prod_id,name);
relationships(prod_id,cat_id);
It is a one-to-many relationship.
So, given a category name say "Books". How do I find all the products that come under books?
As an example,
categories(1,Books);
categories(2,Phones);
products(302,Sherlock Holmes);
relationships(302,1);
You need to JOIN the three tables.
SELECT p.*
FROM relationships r
INNER JOIN products p
ON p.prod_id = r.prod_id
INNER JOIN categories c
ON c.cat_d = r.cat_id
WHERE c.name = 'Books'
You have to join tables on related columns and specify WHERE clause to select all records where category name = 'Books'
SELECT p.*
FROM categories c
JOIN relationships r ON c.cat_id = r.cat_id
JOIN products p ON r.prod_id = p.prod_id
WHERE c.name = 'Books' -- or specify parameter like #Books
In SQL you often join related tables and beginners tend to join, whatever the situation. I would not recommend this. In your case you want to select products. If you only want to show products data, select from products only. You want to select products that are in the category 'Books' (or for which exists an entry in category 'Books'). Hence use an IN or EXISTS clause in order to find them:
select * from products
where prod_id in
(
select prod_id
from relationships
where cat_id = (select cat_id from categories where name = 'Books')
);
Thus you get a well structured query that tells the reader easily how the tables are related and what data you are actually interested in. Later, with different tables and data to select, this may keep you from duplicate result rows that you must get rid of by using DISTINCT or from getting wrong aggregates (sums, counts, etc.), because of mistakenly considering records multifold.
try this:
select p.Prod_id,p.name
from products p inner join relationships r on
p.prod_id = r.prod_id
where r.cat_id = (select cat_id from categories where name = 'books')
or
select p.Prod_id,p.name
from products p inner join relationships r on
p.prod_id = r.prod_id inner join categories c on c.cat_id = r.cat_id
where c.name = 'books'

MySQL select where row is greater than one

I am working on a query that is joining multiple tables to drill down to get the number of subscribers who voted by region where subscribers have more than one vote.
The issue I am stuck at is trying to write in the query of figuring out the calculation of where subscribers voted more than one.
SELECT COUNT(*), regions.name,
(SELECT COUNT(*) FROM votes
LEFT JOIN profiles on votes.subscriber_id = profiles.subscriber_id
LEFT JOIN countries on profiles.country_id = countries.id
WHERE countries.region_id = regions.id GROUP BY votes.subscriber_id) as vote_count
FROM subscribers
LEFT JOIN profiles on subscribers.id = profiles.subscriber_id
LEFT JOIN countries on profiles.country_id = countries.id
LEFT JOIN regions on countries.region_id = regions.id
LEFT JOIN votes on subscribers.id = votes.subscriber_id
WHERE subscribers.created_at < '2011-04-22 00:00:00'
GROUP BY regions.id
HAVING vote_count > 1;
With the above query I am getting the error of, Subquery returns more than 1 row
Any ideas?
The section
SELECT COUNT(*) FROM votes
LEFT JOIN profiles on votes.subscriber_id = profiles.subscriber_id
LEFT JOIN countries on profiles.country_id = countries.id
WHERE countries.region_id = regions.id GROUP BY votes.subscriber_id
is returning more than one result. Try removing the "GROUP BY votes.subscriber_id" which should solve the problem
if your subquery:
(SELECT COUNT(*) FROM votes
LEFT JOIN profiles on votes.subscriber_id = profiles.subscriber_id
LEFT JOIN countries on profiles.country_id = countries.id
WHERE countries.region_id = regions.id GROUP BY votes.subscriber_id)
returns more than 1 row, then it will error, because it's trying to put a collection of rows into the value vote_count. You could solve this by guaranteeing the query has only 1 row result by adding a HAVING clause.
Since you place the sub query in the SELECT part of the query, only one return value is expected (since result sets are two dimensional).
You have to add somewhere in the inner query's WHERE clause a match to the outer query to make sure only one row matches.
What COUNT(*) is it you're looking for that matches regions.name? You have to connect the inner query to that.
Try putting the HAVING vote_count > 1 clause in the subquery. Also, try the subquery on its own to see what it's yielding.