2

How to use multiple columns with a single COUNT?

Assume that there is a table demo with these data:

id |  col1  |  col2  |    
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*  
1  |'alice' | 'book1'|  
2  |'bob'   | 'book1'|  
3  |'alice' | 'book2'|  
4  |'alice' | 'book3'|

I want to find the count of all the combination of user and book name.

I have tried that if i run with distinct, everything is alright.
select count(distinct col1, col2) from demo

However, when i remove distinct, then the sql statement will not be passed in mysql console.
select count(col1, col2) from demo

Question is how to use COUNT with multiple columns in MySql?

5

There are several things you can count with COUNT() function:

  • count(*) : rows
  • count(col1) : rows where col1 is not null
  • count(col2) : rows where col2 is not null
  • count(distinct col1) : distinct col1 values.
  • count(distinct col2) : distinct col2 values.
  • count(distinct col1, col2) : distinct (col1, col2) values combinations.

Tested at SQLfiddle:

    select 
        count(*)             as count_rows,
        count(col1)          as count_1,
        count(col2)          as count_2,
        count(distinct col1) as count_distinct_1,
        count(distinct col2) as count_distinct_2,
        count(distinct col1, col2) as count_distinct_1_2
    from demo ;

But count(col1, col2) is not valid syntax:

select 
    count(col1, col2) 
from demo ;

gives an error:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'col2) from demo' at line 2.

  • that's right, i get the same error about using count(col1, col2). what makes me confused is that whether mysql doc mention this illegal usage. UPDATED i have find that there is no doc about using count(col1, col2) without distinct. – andy Jan 28 '16 at 8:48
  • 2
    No doc == invalid. – Rick James Jan 29 '16 at 3:28
1

Obviously, COUNT(DISTINCT) with multiple columns counts unique combinations of the specified columns' values. However, one other important point is that a tuple is counted only if none of the individual values in the tuple is null. If that last aspect of the behaviour is what you are trying to achieve, you could emulate it using a conditional inside COUNT. It could be either the standard-compliant CASE:

SELECT
  COUNT(CASE WHEN col1 IS NOT NULL AND col2 IS NOT NULL THEN 1 END)
FROM
  demo
;

or the MySQL-specific IF function:

SELECT
  COUNT(IF(col1 IS NOT NULL AND col2 IS NOT NULL, 1, NULL))
FROM
  demo
;

where instead of the 1 you can put any non-null constant. A row will be counted only if neither col1 nor col2 is null.

The obvious flaw of this workaround (either variation) is that it is clearly rather unwieldy and will become ridiculously long very quickly as you add more columns to account for.

It is possible to shorten the expression somewhat by choosing a less clear syntax. In particular, you could replace the COUNT with SUM and treat the predicates as numbers (1/0) in an arithmetic expression:

SELECT
  SUM( (col1 IS NOT NULL) * (col2 IS NOT NULL) )
FROM
  demo
;

In the context of the arithmetic operator * the logical result of the IS NOT NULL operator is implicitly converted to a number, 1 for True, 0 for False. With only 1s and 0s the * operator works as an equivalent of the logical AND: the final result will be 1 (True) only if each operand is 1; otherwise the result will be 0 (False). Adding up (SUM) the 1s is equivalent to counting the truths.

So again, the above statement will count only the rows where neither col1 nor col2 is null.

0
select count(*) from (select distinct col1, col2 from demo) as distinctAll
  • 3
    I'm confused by your answer. As explained by the OP and confirmed by ypercube's answer, COUNT(DISTINCT col1, col2) already works fine in MySQL, you don't need to work around it by introducing a nested SELECT DISTINCT. What the OP is (or was) having problem with is how to do just COUNT(col1, col2) (without the DISTINCT). Or maybe there's more to what you are suggesting here? Could you perhaps edit your answer with an explanation? (Please note also that COUNT(DISTINCT col1, col2) is not the same as select count(*) from (select distinct col1, col2 from demo) as distinctAll.) – Andriy M Nov 12 at 20:43
  • 1
    Welcome to DBA.SE! Please could you edit your answer to add commentary as to why this would solve the OP's problem and why it may be better than the ones that have already been posted. Thanks! – Mr.Brownstone Nov 13 at 23:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.