Select grouped by two columns with Count - mysql

Im having problems trying to understand how to build this query.
My data scheme:
id category name userid
1 sports football 1
2 cars ferrari 1
3 sports basketball 1
4 film Matrix 9
5 film Fauno 9
6 sports Surf 3
As you can see the category can be repeated even for a same user id because the name field is different. So my idea is to get the categories of a set of users and the amount of users for each categories on that set.
Lets say i have the set of user set_of_user = (1,9,3), If i run the query
SELECT something FROM category_table WHERE userid IN set_of_user SOME CONDITION HERE
The correct result should be:
category: sports
users: 2
category: cars
users: 1
category: film
users: 1
My best shot was:
SELECT userid, category, COUNT(userid) as users from interests WHERE `userid` in ' . $norm_info_ids . ' GROUP BY category
But this gave a bad result, how can i solve this?

I think this is what you're looking for using COUNT with DISTINCT, along with GROUP BY:
select category, count(distinct userid)
from interests
where userid in (1,3,9)
group by category
SQL Fiddle Demo
Resulting in:
CATEGORY COUNT(DISTINCT USERID)
cars 1
film 1
sports 2

First you need to select the distinct paring of category and user id
select t.category, count(t.user_id)
from
(
SELECT distinct category,user_id
from tab
where user_id in (1,3,9)
) t
group by t.category

Related

MySQL: Select rows where field contains unique value

In MySQL database, I have a products table containing various product data, including company.
id
name
company
1
Product 1
AAA
2
Another product
BBB
3
One more product
CCC
4
Item ZZZ
BBB
5
Product A
AAA
6
Product uT
DDD
7
Product 2z
AAA
Now I want to build a query which will select all products which have a unique company - I mean a company, which appears only once in the whole table. In the above example - row 3 with company CCC and row 6 with company DDD.
How can I achieve this?
You can use count(id) over(partition by company)
select id, name, company from
(select id, name, company , count(id) over(partition by company) cnt
from products) t
where cnt = 1;
Fiddle
You can use GROUP BY ... HAVING clause to find solo companies, then join to them by the company name.
SELECT * FROM products p
JOIN
(SELECT company FROM products
GROUP BY company
HAVING COUNT(*) = 1) pg
ON p.company = pg.company
SQLFiddle here
MySQL will actually let you do this even simpler query. This works in this circumstance because there is only one row in the group you are looking for. If however, you were looking for all the products for companies that have 2 products, the simpler version won't work anymore, as you'll only get one row back. The original query would continue to work with other HAVING clauses like HAVING COUNT(*) > 10
SELECT id, product, company
FROM products
GROUP BY company
HAVING COUNT(*) = 1
You need to group by company and then only select the rows that have one company:
SELECT `id`, `name`, `company` FROM `products` GROUP BY `company` HAVING COUNT(*)=1;

Guidance required for sql query

I have a database with one table as shown below. Here I'm trying to write a query to display the names of medication manufactured by the company that manufactures the most number of medications.
By looking at the table we could say the medication names which belongs to the company id 1 and 2 - because those company manufactures the most medication according to this table, but I'm not sure how to write a query for selecting the same i said before.
ID | COMPANY_ID | MEDICATION_NAME
1 1 ASPIRIN
2 1 GLUCERNA
3 2 SIBUTRAMINE
4 1 IBUPROFEN
5 2 VENOFER
6 2 AVONEN
7 4 ACETAMINOPHEN
8 3 ACETAMINO
9 3 GLIPIZIDE
Please share your suggestions. Thanks!
Several ways to do this. Here's one which first uses a subquery to get the maximum count, then another subquery to get the companies with that count, and finally the outer query to return the results:
select *
from yourtable
where companyid in (
select companyid
from yourtable
group by companyid
having count(1) = (
select count(1) cnt
from yourtable
group by companyid
order by 1 desc
limit 1
)
)
SQL Fiddle Demo
This Query might work. I have not tested but the logic is correct
SELECT MEDICATION_NAME
FROM TABLE where
COMPANY_ID=(SELECT
MAX(counted)
FROM ( SELECT COUNT(*) AS counted FROM TABLE ) AS counts);

Is there anyway to perform a Count() when using Min()?

The statement below is to get all non-duplicate IDs from the products table. Is there a way I can get the total count of rows that are outputted by this sql statement?
select min(product_id) from products
where market_code = 'germany'
group by product_code
sample table data:
product_id market_code product_code
1 uk AAA
1 uk AAA
1 uk AAA
2 germany BAA
2 germany BAA
3 uk BAA
Thanks
You can simply do this:
SELECT COUNT(*)
FROM
(
select min(product_id) from products
where market_code = 'germany'
group by product_code
) AS t;
Actually your query is not what you said "The statement below is to get all unique/non-duplicate IDs from the products table." , It will select lowest product_id for product_code , not unique , for example if there are product_id - 2 and product_id - 3 for product_code A , it will only return product_id - 2 , it is a minimum value not unique , if you want unique you could do this way
SELECT product_code,product_id,count(*)
FROM TABLE
GROUP BY product_code,product_id
if you want just unique/non-duplicate ID-s and their count you can select with this query
SELECT product_id,count(*)
FROM table
GROUP BY product_id
The statement:
select min(product_id)
from products
where market_code = 'germany'
group by product_code;
is going to have as many rows as there are product code values in Germany. If you assume that a given product id never has two codes (which is true of your sample data), then the following counts the products in Germany without using product id at all:
select count(distinct product_code)
from products
where market_code = 'germany';

MySQL query to count the number of entries grouped by name

I am trying to do a simple query that will count the number of reviews for each company in a database table as follows grouped by name
e.g reviews table
id company_id review
1 1 Great
2 1 Ok
3 1 Bad
4 2 Nice
So this would return company id 1 with 3, and company id 2 with 1. Any ideas on the easiest solution
select company_id, count(company_id) from tablename group by company_id
try
SELECT company_id,Count(1) FROM reviews GROUP BY company_Id;

getting individual records from a group by

I have two tables, one is a table of names with a category tag and the other is a table of scores for each name
ID Name Category
1 Dave 1
2 John 1
3 Lisa 2
4 Jim 2
and the score table is
PersonID Score
1 50
2 100
3 75
4 50
4 75
I would then like a query that returned something like
Category TotalScore Names
1 150 Dave, John
2 200 Lisa, Jim
Is this possible to do with one query?
I can get the totals with a sum query and grouping by category but cannot see a way to get the names as I would like.
Many thanks
You need to use group_concat:
select Category, sum(Score) as TotalScore, group_concat(Name) as Names from categories
join scores on scores.category = categories.category
group by category
Or even better:
group_concat(DISTINCT Name ORDER BY Name ASC SEPARATOR ',') as names
Just add group_concat(Name) as names into your sum query.
Here is a solution working for Postgres (which doesn't have a group_concat() function):
select category, sum(score) as TotalScore, array(select id from perso where category=P.category order by id) as Names from perso P JOIN scores S ON S."PersonID" = P.id GROUP BY category;
(I know this was a MySQL question, but nonetheless someone might google it up but needs an answer for Postgres :) )