How to execute group by in another group by in mysql? - mysql

I have 2 tables: cars and lands:
cars (id, land_id)
lands (id, district_id, location)
I need to get count of cars per each district. What I have now:
SELECT district_id, COUNT(*)
FROM lands
GROUP BY district_id
But of course it returns only count of lands per each district. How to get count of cars?
Expected result:
district_id | cars_count
1 | 30
3 | 10
...

The problem that you select only from lands table, when you also need to join cars table.
SELECT l.id, count(c.land_id)
FROM lands as l LEFT JOIN cars as c ON l.id = c.land_id
GROUP BY l.id

left join these 2 tables based on land_id(cars) and id(lands)
select a.id,
count(b.id)
from lands a
left join cars b on a.id=b.land_id
group by 1;

Related

SQL select inside select

I have 3 tables.
person{personid,name, etc}
bid{bidid,personid,etc}
rating{ratingid,bidid,rating}
A person gets the rating after the bid is accepted by customers. So 1 bid = 1 rating.
And then the person bids another order, but the rating won't show up.
I already tried:
SELECT a.namausaha,ROUND(AVG(c.rating)) AS rating,a.kota,a.kontak,b.bidprice,a.mitraid
FROM tb_mitra a
JOIN tb_bid b ON b.mitraid=a.mitraid
LEFT JOIN tb_rating c ON c.bidid=b.bidid
WHERE b.orderid='OD004' AND b.statusbidid='1'
GROUP BY a.mitraid
but it doesn't work.
How to do it? I want to show the rating for every person.
Some rating return null due to left join
Try this
SELECT a.name,
ROUND(AVG(CASE WHEN c.rating IS NULL THEN 1 ELSE c.rating END )) AS rating,
a.etc,b.etc,a.personid
FROM person a
JOIN bid b ON b.personid=a.personid
LEFT JOIN rating c ON c.bidid=b.bidid
GROUP BY a.personid
SQL Fiddle

how to get result of join also for records that dont have a joined record with another table?

I have this query:
SELECT suppliers.id, count(*)
FROM suppliers
INNER JOIN supplier_addresses
ON suppliers.id = supplier_addresses.supplier_id
GROUP BY suppliers.id;
this gives my a table of supplierId and count of its addresses in the supplier_addresses table. But it only shows me suppliers that have at least 1 address.
I want to see in the result also count of 0 addresses...for example:
supplier.id | count(*)
1 3
2 0
3 1
4 9
in my query I dont see the second record.
Use LEFT JOIN
SELECT suppliers.id, count(supplier_addresses.supplier_id )
FROM suppliers
LEFT JOIN supplier_addresses
ON suppliers.id = supplier_addresses.supplier_id
GROUP BY suppliers.id;

Count comments and get average rating from mysql

I just can't figure out how to get average rating and count comments from my mysql database.
I have 3 tables (activity, rating, comments) activity contains the main data the "activities", rating holds the ratings and comments - of course, the ratings.
activity_table
id | title |short_desc | long_desc | address | lat | long |last_updated
rating_table
id | activityid | userid | rating
comment_table
id | activityid | userid | rating
I'm now trying to the data from activity plus the comment_counts and average_rating in one query.
SELECT activity.*, AVG(rating.rating) as average_rating, count(comments.activityid) as total_comments
FROM activity LEFT JOIN
rating
ON activity.aid = rating.activityid LEFT JOIN
comments
ON activity.aid = comments.activityid
GROUP BY activity.aid
...doesn't do the job. It gives me the right average_rating, but the wrong amount of comments.
Any ideas?
Thanks a lot!
You are aggregating along two different dimensions. The Cartesian product generated by the joins affects the aggregation.
So, you should aggregate before the joins:
SELECT a.*, r.average_rating, COALESCE(c.total_comments, 0) as total_comments
FROM activity a LEFT JOIN
(SELECT r.activityid, AVG(r.rating) as average_rating
FROM rating r
GROUP BY r.activityid
) r
ON a.aid = r.activityid LEFT JOIN
(SELECT c.activityid, COUNT(*) as total_comments
FROM comments c
GROUP BY c.activityid
) c
ON a.aid = c.activityid;
Notice that the outer GROUP BY is no longer needed.

select count items each group

I have two tables category and adverts, i need to select all categories and the number of adverts it has in the adverts table that has at least count greater than zero
the category table
cat_id | Name
----------------
1 | Toys
2 | fashion
3 | electronics
The adverts table
cat_id | title
----------------
1 | a
2 | b
2 | c
1 | d
2 | e
what i expect
cat_id | count | Name
-----------------------
1 |2 | a
2 |3 | b
The query i tried
Select
c.name, c.cat_id,c.parent_id, #count:= (Select Count(av.cat_id) From adsview av Where av.cat_id = c.cat_id)
from
category c WHERE #count > 0
i am getting and empty result, what am i doing wrong?
If you want to make sure that the cat_id from category table are in adverts table you need to join as
select
c.cat_id,
c.Name,
count(a.cat_id) as `count`
from category c
join adverts a on a.cat_id = c.cat_id
group by c.cat_id ;
select cat_id, count(*)
from adverts
group by cat_id;
So the mySQL query engine will grab every single row from the adverts table, it'll put them into neat piles where all rows in the pile have the same category, it'll count the number of rows in each pile, and then it'll return to you a result row for each pile with the pile's id and the number of rows.
Now lets add something: we want to also get the category's name. So we indicate that in the select clause, and add a join to the from clause. The join says "for every row in table a, consider it alongside every row in table b. if some condition holds, put this combined row into the from set". You can see that joins are actually quite slow in SQL (relatively).
select c.cat_id, count(*) as count, c.name
from adverts as a join categories as c on a.cat_id = c.cat_id
group by c.cat_id;
Note also that I've aliased the tables as a and c respectively, so as to remove the ambiguity over the column name cat_id (otherwise the mySQL query engine may get confused).
You can try this, mate:
SELECT
c.cat_id,
COUNT(a.cat_id) AS count,
a.title
FROM
category c
LEFT JOIN adverts a ON a.cat_id = c.cat_id
GROUP BY
c.cat_id
HAVING
count > 0;
or this:
SELECT
c.cat_id,
COUNT(a.cat_id) AS count,
a.title
FROM
category c
INNER JOIN adverts a ON a.cat_id = c.cat_id
GROUP BY
c.cat_id;
You have to use group by function like below
select cat_id, count(*) as count
from adverts
group by cat_id;

Select statement that that counts total number of distinct entries in one table, depending on data from another table

I have two tables: DATA and USERS
USERS
id sqft postal province city
==========================================================
1 1 Y7R BC Vancouver
2 2 Y7R BC Vancouver
3 1 L5B ON Toronto
and
DATA
id uid power
=======================
1 1 1000
2 2 1300
3 1 1500
uid in table DATA matches to id in table USERS
I want to be able to count the the number of distinct uid in DATA where the postal code is Y7R and sqft is 1
SELECT COUNT(id)
FROM `DATA` AS `d`
INNER JOIN `USERS` AS `u`
ON u.id=d.uid
WHERE u.postal='Y7R' AND u.sqft=1
GROUP BY u.id;
They should be distinct anyway if you have a proper schema, if so just remove the group by clause.
SELECT COUNT(DISTINCT D.UID) FROM DATA D
LEFT JOIN USERS U ON D.UID=U.ID
WHERE U.POSTAL='Y7R' AND U.SQFT=1)
In case you need distinct
You can use this solution:
SELECT COUNT(DISTINCT a.id)
FROM USERS a
JOIN DATA b ON a.id = b.uid
WHERE a.sqft = 1 AND
a.postal = 'Y7R'
Try this one:
SELECT COUNT(DISTINCT a.id)
FROM USERS a
INNER JOIN DATA b
ON a.id = b.uid
WHERE a.sqft = 1 AND
a.postal = 'Y7R'