Não funciona como você acha que deveria e a documentação explica o significado de
DISTINCT
:trata-se de linhas distintas :(fonte:http://dev.mysql.com /doc/refman/5.7/en/select.html )
Você precisa agrupar as linhas por usuário para obter uma única linha para cada usuário, mas, infelizmente, não é possível obter a pontuação mais recente dessa maneira. Você pode obter a pontuação máxima, mínima, média e outros valores calculados. Verifique a lista de
GROUP BY funções agregadas
. A consulta
Esta é a consulta que obtém os valores que você precisa:
SELECT u.fsname, u.emailaddress, la.score
FROM users u
INNER JOIN attempts la # 'la' from 'last attempt'
ON u.emailaddress = la.emailaddress
LEFT JOIN attempts mr # 'mr' from 'more recent' (than last attempt)
ON la.emailaddress = mr.emailaddress AND la.datetime < mr.datetime
WHERE mr.datetime IS NULL
Como funciona
Ele une a tabela
users
(alias como u
) com a tabela tentativas
(alias como la
, abreviação de "última tentativa") usando emailaddress
como a coluna correspondente. É a junção que você já tem na sua consulta, adicionei os aliases porque eles ajudam a escrever menos a partir desse ponto. Em seguida, ele se junta às
tentativas
tabela novamente (alias como mr
de "mais recente que a última tentativa"). Corresponde a cada tentativa de la
com todas as tentativas de mr
do mesmo usuário (identificado por seu endereço de e-mail
) e que têm um datetime
mais recente . O LEFT JOIN
garante que cada linha de la
corresponde a pelo menos uma linha de mr
. As linhas de la
que não têm uma correspondência em mr
são as linhas que têm os maiores valores de datetime
para cada endereço de e-mail
. Eles são combinados com linhas cheias de NULL
(para o sr
papel). Finalmente, o
WHERE
cláusula mantém apenas as linhas que têm NULL
no datetime
coluna da linha selecionada de mr
. Estas são as linhas que correspondem às entradas mais recentes de la
para cada valor de emailaddress
. Observações de desempenho
Para executar rapidamente esta consulta (qualquer consulta! ) precisa de índices nas colunas usadas no
JOIN
, ONDE
, GRUPAR POR
e ORDEM POR
cláusulas. Você não deve usar
endereço de e-mail
na tabela tentativas
para identificar o usuário. Você deve ter um PK
(chave primária) na tabela users
e use isso como um FK
(chave estrangeira) na tabela tentativas
(e outras tabelas que se referem a um usuário). Se endereço de e-mail
é o PK
da tabela usuários
altere-o para um UNIQUE INDEX
e use um novo INTEGER AUTO INCREMENT
coluna ed userId
como PK
em vez de. Os índices em colunas numéricas são mais rápidos e usam menos espaço do que os índices em colunas de string.