Multiple count values on one column - php

I want to query my database and get counts of the occurences of each id in a single column.
The two tables related to this query are:
categories: this table has a list of all categories with titles
id | title
----------
1 | project
2 | tech
3 | other
category_news: this table is used to assign news items to categories, each news item can be in multiple categories
id | category_id | news_id
--------------------------
1 | 1 | 2
2 | 1 | 5
3 | 1 | 3
4 | 2 | 4
5 | 3 | 2
6 | 3 | 1
I would like to get a result of (doesnt have to be an array, I can sort out the results of a query, just using an array below for an example of the returned results):
array(
'project' => 3
'tech' => 1
'other' => 2
);
Where the key is the category title and the value is the total number of news items in each category. I know that I could do it with a query for each category:
select count(cn.category_id), c.title from category_news cn join categories c on c.id = cn.category_id where category_id = 1
But my question is, can I do it with one query to get all the counts? As if I have 100 categories thats 100 queries my way and I would love to do it in one.
Any help would be much appreciated
Regards
Luke

Try this:
SELECT c.title, count(cn.category_id)
FROM categories c
LEFT JOIN categories_news cn
ON c.id = cn.category_id
GROUP BY c.title

This will work(tested):
SELECT COUNT(cn.category_id), c.title
FROM category_news cn
JOIN categories c ON c.id = cn.category_id
GROUP BY cn.category_id

Yes, you can. You have to use a query like the following (tested)
SELECT count( * ) , c.title
FROM category_news cn
JOIN categories c ON c.id = cn.category_id
WHERE 1
GROUP BY cn.category_id

Related

count total volume by category

I have 3 tables
Company_categories
companies
daily_rates
I want to count total volume industry wise of all the company exist within the category of companies
for example category A contains 3 companies and category B contains 5 companies so I want to sum total volume of all 3 companies in category A and so on for all categories I tried to do so but I am confused how to do with 3rd table as of I am easily been able to count the companies contains in category but not sure how to count the volume of all companies exist in a category
my table structure
company_categories
id name
+------------+----------+
| 1 | A |
|------------|----------|
| 2 | B |
|------------|----------|
companies
id name category
+------------+----------+-----------+
| 1 | co 1 | 1 |
|------------|----------|-----------|
| 2 | co 2 | 2 |
|------------|----------|-----------|
| 3 | co 3 | 1 |
|------------|----------|-----------|
daily_stock_rates
id traded_volume company_id
+------------+------------------+---------------+
| 1 | 40 | 1 |
|------------|------------------|---------------|
| 2 | 80 | 2 |
|------------|------------------|---------------|
| 3 | 30 | 3 |
|------------|------------------|---------------|
here is my code
$sql = mysqli_query($connect, "SELECT c.id category_id, c.name category_name, com.id, com.category count( dsr.total_traded_volume ) total_volume
FROM company_categories c
INNER JOIN companies com ON c.id = com.category
LEFT JOIN daily_stock_rates dsr ON com.id = dsr.company_id
GROUP BY com.category
ORDER BY total_volume DESC LIMIT 10");
while($data = mysqli_fetch_assoc($sql)) {
echo $data['category_name'] . ": .".$data['total_volume'];
echo "<br />";
}
Can Anyone help me out
joint twice to get all the rates related to the category
SELECT cat.name, SUM(rat.traded_volume) volume
FROM company_categories cat
JOIN companies comp ON comp.category = cat.id
JOIN daily_stock_rates rat ON rat.company_id = comp.id
GROUP BY cat.name
ORDER BY volume DESC
LIMIT 10
Most important diff to your query:
you need SUM(), not COUNT()
select only what you asked: volume by category. You cannot select
names of companies alongside (what company you would want to see
there anyway)
I don't think it's the join you got wrong, it's the select list and the group by clause.
First of all, if you want the total of the volume, then use sum(), not count(). Also, do not include so many fields in the select list if you want the total by category:
SELECT c.id category_id, c.name category_name, sum( dsr.total_traded_volume ) total_volume
FROM company_categories c
LEFT JOIN companies com ON c.id = com.category
LEFT JOIN daily_stock_rates dsr ON com.id = dsr.company_id
GROUP BY c.id
ORDER BY total_volume DESC LIMIT 10

Mysql IN query instead of multiple AND conditon

I have three mysql tables, category,students and student_category. for each student there is 1 or more category will be there and it is stored in student_category as follows.
1) Categgory
----------------------------
id | category_name
---------------------------
1 | A
2 | B
3 | C
4 | D
2) Students
--------------------------
id | name
--------------------------
1 | John
2 | Kumar
3 | Ashok
4 | Jorge
5 | Suku
-------------------------
2) student_category
-----------------------------------------
id | student_id | category_id
-----------------------------------------
1 | 1 | 2
2 | 1 | 4
3 | 2 | 3
4 | 2 | 1
5 | 3 | 2
------------------------------------------
I need to select students which contain category_id 2 and 4.
i used query as follows but it return either students contain category 2 or category 4.
select A.name from students A, student_category B where A.id=B.student_id
and B.category_id IN (2,4)
Try this query:
SELECT t1.id,
t3.name
FROM students t1
INNER JOIN student_category t2
ON t1.id = t2.student_id
INNER JOIN students t3
ON t1.id = t3.id
WHERE t2.category_id IN (2, 4)
GROUP BY t1.id
HAVING COUNT(DISTINCT t2.category_id) = 2
Explanation:
This query joins together the students and student_category tables, and then removes all records which are not category 2 or 4. This means that each student would then only have category 2 and 4 records associated with him. The HAVING clause then restricts further by requiring that a student have two distinct categories, which if true must mean that the student has both category 2 and 4.
Demo here:
SQLFiddle
try this :
select name from Students where id in (select student_id from student_category where category_id in (2,4))
your query is fine btw.
Try this one:
select
s.name
from
Students s,
Categgory c,
student_category sc
where
sc.student_id = s.id
and sc.category_id = c.id
and c.id = 2
and c.id = 4
You can check it on SQL Fiddle.
Have to take distinct student name as it will repeat if a student falls in more than one category.

Mysql query inside a query

First, apologies if the title doesn't match the question. Well, the problem is how to build this query...
I have a table called category It contains categories of my stuff(movies). It's like this...
--------------------------------
ID | name | parent_category
--------------------------------
1 | love | 0
2 | action | 0
3 | fear | 0
4 | passion| 1
5 | danger | 2
6 | death | 3
--------------------------------
So, as you see, each category has a parent category. Except the first 3. They're parents.
And movies table is like this...
--------------------------------
ID | name | category
--------------------------------
1 | aaaa | 1
2 | bbbbbb | 2
3 | cccc | 2
4 | ddddddd| 1
5 | eeeeee | 3
6 | fffff | 3
--------------------------------
So, what i want to do is, to select movies by parent category. Which means if I click category, love, it should select all the movies of categories that having love as the parent category.
So, how to write this in a single query ?
If the parents are only one level deep, then you can use joins:
select m.*,
coalesce(cp.id, c.id) as parent_id,
coalesce(cp.name, c.name) as parent_name
from movies m left join
categories c
on m.category = c.id left join
categories cp
on c.parent_category = cp.id;
Actually, if you only want the id, you don't need two joins:
select m.*,
(case when c.parent_id > 0 then c.parent_id else c.id end) as parent_id
from movies m left join
categories c
on m.category = c.id ;
Or, more simply:
select m.*, greatest(c.parent_id, c.id) as parent_id
. . .
to select rows filtered by condition on secend table use join in FROM clause or subquery in condition with IN or EXISTS function. To compare field with some string you can use LIKE operator.
If you are filtering based on parent_category -
SELECT b.*, a.name FROM movies b
LEFT JOIN categories a ON a.id = b.category
WHERE a.parent_category = 1;

How to select all categories and count number of each category articles in MySQL

Category table:
id, name
---------
1 cat1
2 cat2
3 cat3
4 cat4
Article table:
id, cid, title
--------------
1 1 title1
2 3 title2
3 1 title3
4 2 title4
How to select all categories and count number of each category articles in MySQL? I need a mysql query that will select all category and total count of articles belonging to each category and order by category id.
Expected output table:
+-------+-------+
| name | count |
+-------+-------+
| cat1 | 2 |
| cat2 | 1 |
| cat3 | 1 |
| cat4 | 0 |
+-------+-------+
SELECT
c.`name`,
COUNT(a.cid) AS `count`
FROM
categories c
LEFT JOIN article a ON c.id = a.cid
GROUP BY
c.`name`
ORDER BY
c.`name`
You can also use subquery like
SELECT c.name,(select count(*) from article where cid = c.id) as count FROM cat c WHERE 1 GROUP BY c.id
Try this:
SELECT c.`name`, count(a.cid) as count FROM category
LEFT JOIN article
ON c.id = a.cid
GROUP BY a.cid
select c.name,count(b.title)count from category a, article b where c.id = a.cid group by c.name order by a.cid;
I hope this will work. Please check.
select
Category.name.
ifnull(count(Article.cid),0) as count
FROM
Category
LEFT JOIN
Article
on
Article.cid=Category.id
group by
Category.Id

How do I select all categories per product and returning this in one row per product?

I'm having a bit of a brain freeze now, because this should be very easy (I think).
I have three tables:
products list
categories list
category_map (links product and category)
I want to list products with its categories (names). One product may have many categories.
// This query
SELECT a.id, a.name, b.category
FROM sl_link_product_category c
LEFT JOIN sl_product a ON c.fk_productID = a.id
LEFT JOIN sl_category b ON c.fk_categoryID = b.id
WHERE c.fk_categoryID = b.id
ORDER BY a.id
// Gives me this result
| 1 | product 1 | cat 1 |
| 1 | product 1 | cat 2 |
| 1 | product 1 | cat 3 |
| 2 | product 2 | cat 2 |
| 2 | product 2 | cat 4 |
Now, in the final result set, I want an array with products where each product has an array of categories.
My question is; Do I have to work with the result set in PHP to achieve my goal? Or is it possible in MySQL to put all categories (comma separated) in one variable / column?
The GROUP_CONCAT function is what you're looking for:
SELECT a.id, a.name, GROUP_CONCAT(b.category)
FROM sl_link_product_category c
LEFT JOIN sl_product a ON c.fk_productID = a.id
LEFT JOIN sl_category b ON c.fk_categoryID = b.id
GROUP BY a.id, a.name
ORDER BY a.id

Categories