Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Executando várias consultas no MySQL sem usar subconsulta


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.