0
Good morning, I have the following table:
+------------+--------------+------+-----+----------------+
| Field | Type | Null | Key | Extra |
+------------+--------------+------+-----+----------------+
| idAcesso | int(11) | NO | PRI | auto_increment |
| dataAcesso | date | NO | | |
| contato | tinyint(1) | YES | | |
+------------+--------------+------+-----+----------------+
Her goal is to know how many people, from those who accessed a given page, came in contact. There are two contact forms on the page and, the contact column, receives the ID of the form used or the NULL value if you have not contacted.
I need to return the total of lines that were made contact or not grouped for days. More or less this:
+------------+--------------+---------------+------------+
| dataAcesso | totalAcessos | totalContatos | semContato |
+------------+--------------+---------------+------------+
| 2019-09-28 | 98 | 98 | 98 |
| 2019-09-29 | 114 | 114 | 114 |
| 2019-09-30 | 197 | 197 | 197 |
| 2019-10-01 | 185 | 185 | 185 |
| 2019-10-02 | 163 | 163 | 163 |
| 2019-10-03 | 167 | 167 | 167 |
| 2019-10-04 | 93 | 93 | 93 |
| 2019-10-05 | 102 | 102 | 102 |
| 2019-10-06 | 154 | 154 | 154 |
| 2019-10-07 | 295 | 295 | 295 |
+------------+--------------+---------------+------------+
The problem is that these values do not match, the 3 totals have different values and the totalAccesss should be the sum of the other totals.
I can get the correct values with 3 different Sqls but I would like to know if there is a way to do these queries correctly using just one query.
What I’m trying to:
SELECT
dataAcesso,
COUNT( idAcesso ) AS totalAcessos,
COUNT( !ISNULL( contato ) ) AS totalContatos,
COUNT( ISNULL( contato ) ) AS semContato
FROM
acessos
GROUP BY
dataAcesso
Any hint on how I can make this query?
Thank you.
EDIT
An example of how lines can be filled:
+----------+------------+---------+
| idAcesso | dataAcesso | contato |
+----------+------------+---------+
| 1 | 2019-09-28 | 1 |
| 2 | 2019-09-28 | 2 |
| 3 | 2019-09-28 | 2 |
| 4 | 2019-09-28 | NULL |
| 5 | 2019-09-28 | NULL |
| 6 | 2019-09-28 | NULL |
| 7 | 2019-09-28 | NULL |
| 8 | 2019-09-28 | NULL |
| 9 | 2019-09-28 | NULL |
| 10 | 2019-09-28 | NULL |
| 11 | 2019-09-28 | NULL |
| 12 | 2019-09-28 | NULL |
| 13 | 2019-09-28 | NULL |
| 14 | 2019-09-28 | NULL |
| 15 | 2019-09-28 | NULL |
| 16 | 2019-09-28 | NULL |
| 17 | 2019-09-28 | NULL |
| 18 | 2019-09-28 | 1 |
| 19 | 2019-09-28 | 1 |
| 20 | 2019-09-28 | 1 |
+----------+------------+---------+
Ricardo Pontual’s answer eventually led me to the solution, since I did not know that COUNT does not count null values:
SELECT
dataAcesso,
COUNT( idAcesso ) AS totalAcessos,
COUNT( contato ) AS totalContatos,
COUNT( IF(contato > 0, NULL, 1) ) AS semContato
FROM
acessos
GROUP BY
dataAcesso
Thus the
semContato
will not return 0 since in the negative case the value returned will be the one of the first expression that will beNULL
?– Sorack
Did not return 0, but the values still do not match
2019-09-28 | totalAcessos: 20 | totalContatos: 6 | semContato: 2
. With this it is already possible to do what I wanted. The totalAccesss and totalContacts are with the correct values so I could simply dototalAcessos - totalContatos
to get the semContact. I will update the question with the filled table.– Rafael S.
NULLIF is returning NULL when the value is 1, so it ends up counting the contacts in the id 2 form when it should actually count the total of NULL.
– Rafael S.