multiple count in join - mysql

I am trying to get the count of ids from one table with left join in a mysql query. it works well when i have one count. but when i try to add an additional count the result of the second count is the same as first count. so how to fix this query to have two counts.
note: 1 st count result should be based on join condition
2 nd count result should be over all count not based on join

SELECT COUNT(*)
counts all rows.
SELECT COUNT(column_name)
counts just the values that are not NULL in that particular column.
So in your case your first count should be COUNT(a column from your joined table) and your second count should be COUNT(*).
For special cases you can also use boolean expressions. For example
SELECT SUM(my_column = 'foo')
counts just the values where the value in my_column is foo, because the boolean expression returns 1 if true and 0 otherwise.

Related

SQL query which includes COUNT(*) in it's SELECT `clause` confuses me

I'm a newbie in SQL, trying to find my way through.
I have the following diagram:
and I'm being requested to
"Produce a list of number of items from each product which was ordered
in June 2004. Assume there's a function MONTH() and YEAR()"
The given solution is:
SELECT cat_num, COUNT(*)
FROM ord_rec AS O, include AS I
WHERE O.ord_num = I.ord_num AND
MONTH(O.ord_date) = 6 AND
YEAR(O.ord_date) = 2004
GROUP BY cat_num;
What I'm confused about is the COUNT(*). (specifically the asterisk within).
Does it COUNT all rows that are returned from the given query? So the asterisk refers to all of the returned ROWS? or am I far off?
Is it any different than having:
SELECT cat_num, COUNT(cat_num)
Thanks!
The COUNT(*) function returns the number of rows in a dataset using the SELECT statement. The function counts rows with NULL, duplicate, and non-NULL values.
The COUNT(cat_num) function returns the number of rows that do not contain NULL values.
Consider an example:
Block
Range
A
1-10
A
10-1
B
(NULL)
B
(NULL)
B
(NULL)
For this data,using query:
SELECT
COUNT(*),
COUNT(t.`Block`),
COUNT(t.`Range`)
FROM
`test_table` t
You'll obtain results :
count(*)
count(t.Block)
count(t.Range)
5
5
2
I hope that clears your confusion.
The COUNT(*) function returns the number of rows in a table in a query. It counts duplicate rows and rows that contain null values.
Overall, you can use * or ALL or DISTINCT or some expression along
with COUNT to COUNT the number of rows w.r.t. some condition or all of
the rows, depending up on the arguments you are using along with
COUNT() function.
Possible parameters for COUNT()
When the * is used for COUNT(), all records ( rows ) are COUNTed if some content NULL but COUNT(column_name) does not COUNT a record if its field is NULL.
Resources here.

MySQL JOINED table query that adds a Count() column returns 1 when zero match

SELECT sg.date, sg.groupName, sg.highlights, user.display_name as displayName,
COUNT(*) as cmtcnt
FROM `saved_groups` as sg
LEFT JOIN `user` on user.email = sg.userName
LEFT JOIN `user_comments` as uc on sg.groupName = uc.groupName
GROUP BY sg.groupName
I have two tables, saved_groups and user_comments and the second line of the query should (does, it works) return an extra column with the number of comments associated with each group.
However, when a group has zero comments associated with it, the count returns 1 when it should return zero.
How can I fix this query?
I tried: COUNT(*)-1 as cmtcnt -- and that returns zero for the groups without comments, but it also returns an incorrect number (-1) for groups that have associated comments.
I also tried: NULL(Count(*), 0) -- but that errors out with #1582 - Incorrect parameter count in the call to native function 'ISNULL'
I also tried: COALESCE(COUNT(*), 0) as cmtcnt -- and that made no difference whatsoever (returned 1 for all groups with zero comments, correct number for the others)
Suggestions?
COUNT() aggregate function never returns null and COUNT(*) always returns a value greater than 0 because it counts all the rows of the resultset.
What you want is to count the rows of user_comments that match the conditions in the ON clause and you can do this by specifying inside the parentheses the column groupName:
COUNT(uc.groupName)
This way only non-null rows will be counted and you can get 0 if for a specific sg.groupName there is no matching row in user_comments.
You are counting all things from all tables when you say count(*).
Because saved_groups has a row, you get the 1 returned, which is correct.
What you want is to only count the comments. So instead of COUNT(*) as cmtcnt you should use COUNT(uc.*) as cmtcnt.
This tells the query to only count rows from the uc table.

left join with group by returns no rows if table does not contains the specific id

I want to find out how many people rated a specific location. the problem is that my sql ONLY works if the hasVotedLocation table CONTAINS THE ID OF THE SPECIFIC LOCATION. Meaning if nobody voted the specific location i get zero rows.
My sql statement:
select count(*),l.idLoc from Location l
left join hasVotedLocation hvl
on hvl.idLoc=l.idLoc where l.idLoc=2
group by l.idLoc
For idLoc=1 the query should return one row with count(*)=3 and idLoc=1
For idLoc=2 the query should return one row with count(*)=0 and idLoc=2
For idLoc=3 the query should return one row with count(*)=1 and idLoc=3
You can remove the GROUP BY:
select <someid> as idLoc, count(x)
from Location l left join
hasVotedLocation hvl
on hvl.idLoc = l.idLoc ;
This will always return one row. The count() will be 0 if there are no matching rows.
In a GROUP BY query COUNT(*) returns the number of rows in the group. However when the condition in the ON clause of the LEFT JOIN doesn't match any row in the right table, the result will be one row with all columns from the right table filled with NULLs. That is still one row - not zero rows. Thus COUNT(*) will never return a value less than 1 in this query. But the result will also not be "zero rows" (as you stated in your question), as long as the condition in the WHERE clause matches any row in the left table.
To get the number of matches in the right table (the number of votes in your case), you should count the number of non NULL values from the right table. It is usually best to use the same column as in the ON clause (this way the engine can use the same index without a second lookup), which would be COUNT(hvl.idLoc).
select count(hvl.idLoc), l.idLoc from Location l
left join hasVotedLocation hvl
on hvl.idLoc=l.idLoc where l.idLoc = ?
group by l.idLoc
However - If all you need is the number of votes for a specific idLoc value, you can just use a simple COUNT(*) query.
select count(*)
from hasVotedLocation
where idLoc = ?
Note: In this query COUNT(*) will return 0, if the WHERE condition doesn't match any row. This is because SELECT * would return zero rows.

func.count(distinct(...)) does not give the same result as distinct().count()

I have a column with null entries, e.g. the possible values in this column are None, 1, 2, 3
When I count the number of unique entries in the column with session.query(func.count(distinct(Entry.col))).scalar() I get back '3'.
But when I perform the count with session.query(Entry.col).distinct().count(), I get back '4'.
Why does the latter method count the None, but the first doesn't?
In the first case, the resulting query will look like this:
SELECT COUNT(DISTINCT(col)) FROM Entry
... and, as you probably already know, COUNT here won't actually count the NULL values.
In the second case, however, the query is different, as shown in the doc:
SELECT count(1) AS count_1 FROM (
SELECT DISTINCT(col) FROM Entry
) AS anon_1
Now that just counts the total number of the rows returned by SELECT DISTINCT query (which is 4 - NULL is included in the output of DISTINCT queries).
The reason is simple: query.count purpose is to return the number of rows the query would have returned if run without count clause. This method doesn't give you control over which columns should be used to count - that's what func.count(...) is for.
MySQL COUNT doesn't count NULL values, so if you are counting values by a field that has NULL values, that rows won't be counted by COUNT.
DISTINCT returns just number of different values so NULL is included.

MySQL: Count two things in one query?

I have a "boolean" column in one of my tables (value is either 0 or 1).
I need to get two counts: The number of rows that have the boolean set to 0 and the number of rows that have it set to 1. Currently I have two queries: One to count the 1's and the other to count the 0's.
Is MySQL traversing the entire table when counting rows with a WHERE condition? I'm wondering if there's a single query that would allow two counters based on different conditions?
Or is there a way to get the total count along side the WHERE conditioned count? This would be enough as I'd only have to subtract one count from the other (due to the boolean nature of the column). There are no NULL values.
Thanks.
You could group your records by your boolean column and get count for each group.
SELECT bool_column, COUNT(bool_column) FROM your_table
WHERE your_conditions
GROUP BY bool_column
This will obviously work not only for bool columns but also with other data types if you need that.
Try this one:
SELECT
SUM(your_field) as positive_count,
SUM(IF(your_field, 0, 1)) as negative_count
FROM thetable
If they are all either 0 or 1 and you dont mind 2 rows as result you can group by that field and do a count like so:
select field, count(field)
from table
group by field
A simple group clause should do the trick :
SELECT boolField, COUNT(boolField)
FROM myTable
GROUP BY boolField