Contagem de linhas do MySQL de outra tabela para cada registro na tabela

19
SELECT
  student.StudentID,
  student.`Name`,
  COUNT(attendance.AttendanceID) AS Total
FROM
  student
LEFT JOIN attendance ON student.StudentID = attendance.StudentID

Estou tentando contar a última linha, mas conta todos os resultados e retorna um resultado

Estou recebendo algo como

insira a descrição da imagem aqui

como existem vários registros, porque há duas entradas no ID de presença para K1052280. Quero contá-las e retornar o número. Algo como

insira a descrição da imagem aqui

Ali Shaikh
fonte

Respostas:

22

Só falta o GROUP BY

SUA CONSULTA COM O GRUPO POR

SELECT
  student.StudentID,
  student.`Name`,
  COUNT(attendance.AttendanceID) AS Total
FROM
  student
LEFT JOIN attendance ON student.StudentID = attendance.StudentID
GROUP BY student.StudentID,student.`Name`;

DADOS DE AMOSTRA

DROP DATABASE IF EXISTS alishaikh; CREATE DATABASE alishaikh;
USE alishaikh
CREATE TABLE student
(
  StudentID CHAR(8) NOT NULL,
  Name VARCHAR(40),
  PRIMARY KEY (StudentID)
);
INSERT INTO student (StudentID,Name) VALUES
('k1052280','Ali Shaikh'),('k1052287','McKenzie Roth'),
('k1052288','Dacey Sullivan'),('k1052294','Zelda Cantu'),
('k1052295','Kimberly Melton'),('k1052296','Tatianna Cantrell'),
('k1052297','Morgan Thornton'),('k1052298','Allistair Barlow'),
('k1052299','Troy Fulton');
CREATE TABLE attendance
(
  AttendanceID INT NOT NULL AUTO_INCREMENT,
  StudentID CHAR(8) NOT NULL,
  PRIMARY KEY (AttendanceID),
  KEY (StudentID)
);
INSERT INTO attendance (StudentID) VALUES
('k1052280'),('k1052280'),('k1052287'),('k1052287'),
('k1052288'),('k1052295'),('k1052295'),('k1052295');

DADOS DE AMOSTRA CARREGADOS

mysql> DROP DATABASE IF EXISTS alishaikh; CREATE DATABASE alishaikh;
Query OK, 2 rows affected (0.01 sec)
Query OK, 1 row affected (0.00 sec)
mysql> USE alishaikh
Database changed
mysql> CREATE TABLE student
    -> (
    ->   StudentID CHAR(8) NOT NULL,
    ->   Name VARCHAR(40),
    ->   PRIMARY KEY (StudentID)
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO student (StudentID,Name) VALUES
    -> ('k1052280','Ali Shaikh'),('k1052287','McKenzie Roth'),
    -> ('k1052288','Dacey Sullivan'),('k1052294','Zelda Cantu'),
    -> ('k1052295','Kimberly Melton'),('k1052296','Tatianna Cantrell'),
    -> ('k1052297','Morgan Thornton'),('k1052298','Allistair Barlow'),
    -> ('k1052299','Troy Fulton');
Query OK, 9 rows affected (0.00 sec)
Records: 9  Duplicates: 0  Warnings: 0

mysql> CREATE TABLE attendance
    -> (
    ->   AttendanceID INT NOT NULL AUTO_INCREMENT,
    ->   StudentID CHAR(8) NOT NULL,
    ->   PRIMARY KEY (AttendanceID),
    ->   KEY (StudentID)
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO attendance (StudentID) VALUES
    -> ('k1052280'),('k1052280'),('k1052287'),('k1052287'),
    -> ('k1052288'),('k1052295'),('k1052295'),('k1052295');
Query OK, 8 rows affected (0.00 sec)
Records: 8  Duplicates: 0  Warnings: 0

SUA CONSULTA COM O GRUPO POR EXECUTADO

mysql> SELECT
    ->   student.StudentID,
    ->   student.`Name`,
    ->   COUNT(attendance.AttendanceID) AS Total
    -> FROM
    ->   student
    -> LEFT JOIN attendance ON student.StudentID = attendance.StudentID
    -> GROUP BY student.StudentID,student.`Name`;
+-----------+-------------------+-------+
| StudentID | Name              | Total |
+-----------+-------------------+-------+
| k1052280  | Ali Shaikh        |     2 |
| k1052287  | McKenzie Roth     |     2 |
| k1052288  | Dacey Sullivan    |     1 |
| k1052294  | Zelda Cantu       |     0 |
| k1052295  | Kimberly Melton   |     3 |
| k1052296  | Tatianna Cantrell |     0 |
| k1052297  | Morgan Thornton   |     0 |
| k1052298  | Allistair Barlow  |     0 |
| k1052299  | Troy Fulton       |     0 |
+-----------+-------------------+-------+
9 rows in set (0.00 sec)

mysql>

DE UMA CHANCE !!!

RolandoMySQLDBA
fonte
Obrigado por esta explicação clara. Agora, mais uma pergunta. Como posso classificar a tabela em Total ou filtrar os registros em que Total = 0?
usar o seguinte código
adicionar order by Totalapós o grupo por
PSN
@PSN Obrigado pelo lembrete. Na maioria dos casos, GROUP BYdefine o padrão para ORDER BY. Às vezes não. Então, ORDER BYtambém pode ser usado !!!
RolandoMySQLDBA 28/11/19
@RolandoMySQLDBA, desculpe-me por me apegar a esta resposta lúcida, na esperança de uma solução para o meu problema! Vamos fingir que há uma terceira tabela, TestResultcom colunas de (StudentID, Result). Desejo também participar TestResulte, eventualmente, obter COUNT(TestResult.Result)para cada aluno. Por algum motivo, estou obtendo valores em excesso para a COUNT, enquanto as subconsultas retornaram as COUNTs corretas.
Ifedi Okonkwo
Para ajudar a esclarecer, minha consulta é assim: stackoverflow.com/a/24727261/2554788 , mas sem as DISTINCTpalavras - chave. Qual seria o motivo dos COUNTs retornarem algo diferente (geralmente mais alto e, é claro, errado) do que o padrão de subconsulta?
Ifedi Okonkwo