Eu estou querendo saber como escrever esta consulta.
Eu sei que essa sintaxe real é falsa, mas ajudará você a entender o que estou querendo. Eu preciso desse formato, porque faz parte de uma consulta muito maior.
SELECT distributor_id,
COUNT(*) AS TOTAL,
COUNT(*) WHERE level = 'exec',
COUNT(*) WHERE level = 'personal'
Eu preciso disso tudo retornado em uma consulta.
Além disso, ele precisa estar em uma linha, para que o seguinte não funcione:
'SELECT distributor_id, COUNT(*)
GROUP BY distributor_id'
SELECT distributor_id, COUNT(*) AS TOTAL, COUNT(*) WHERE level = 'exec', COUNT(*) WHERE level = 'personal'
Respostas:
Você pode usar uma
CASE
instrução com uma função agregada. Isso é basicamente a mesma coisa que umaPIVOT
função em alguns RDBMS:fonte
COUNT
contará comdistributor_id
sabedoria. nem todas as linhas da tabela, certo?Uma maneira que funciona com certeza
EDIT:
Consulte a quebra de desempenho de @ KevinBalmforth para saber por que você provavelmente não deseja usar esse método e, em vez disso, deve optar pela resposta de @ Taryn ♦. Estou deixando isso para que as pessoas possam entender suas opções.
fonte
sum(case...)
solução deve ser considerada.group by
com o benefício de substituir uma consulta aninhada inteira por uma simples,count(*)
como mostra o @Mihai - com outras simplificações da sintaxe do MySQL.COUNT
conta apenasnon null
valores eDECODE
retornará um valor não nulo1
somente se sua condição for atendida.fonte
distributor_id
será a consulta mostrada? Mostra 1 linha no total.Com base em outras respostas postadas.
Ambos produzirão os valores corretos:
No entanto, o desempenho é bem diferente, o que obviamente será mais relevante à medida que a quantidade de dados aumentar.
Descobri que, assumindo que nenhum índice foi definido na tabela, a consulta usando as SUMs faria uma única varredura de tabela, enquanto a consulta com os COUNTs faria várias varreduras de tabela.
Como exemplo, execute o seguinte script:
Destaque as 2 instruções SELECT e clique no ícone Exibir plano de execução estimado. Você verá que a primeira instrução fará uma varredura de tabela e a segunda fará 4. Obviamente, uma varredura de tabela é melhor que 4.
Adicionar um índice em cluster também é interessante. Por exemplo
A primeira SELEÇÃO acima fará uma única Verificação de Índice em Cluster. O segundo SELECT fará 4 buscas de índice em cluster, mas elas ainda são mais caras que uma única verificação de índice em cluster. Tentei a mesma coisa em uma tabela com 8 milhões de linhas e o segundo SELECT ainda era muito mais caro.
fonte
Para o MySQL, isso pode ser reduzido para:
fonte
Bem, se você tiver tudo em uma consulta, poderá fazer uma união:
Ou, se você puder fazer após o processamento:
Você receberá a contagem de cada nível e precisará resumir todos eles para obter o total.
fonte
UNION
-se muito útil ao gerar um relatório contendo várias instâncias daCOUNT(*)
função.#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') FROM distributors UNION SELECT COUNT() AS EXEC_COUNT FROM distributors WHERE ' at line 1
.Faço algo assim, onde apenas atribuo a cada tabela um nome de sequência para identificá-la na coluna A e uma contagem para a coluna. Então eu uno todos eles para que eles empilhem. O resultado é bonito na minha opinião - não tenho certeza de quão eficiente é comparado a outras opções, mas me deu o que eu precisava.
Resultado:
fonte
a query that I created makes ...
- onde está essa consulta?Com base na resposta aceita pela Bluefeet com uma nuance adicional usando
OVER()
:Usar
OVER()
nada no () fornecerá a contagem total para todo o conjunto de dados.fonte
Eu acho que isso também pode funcionar para você
select count(*) as anc,(select count(*) from Patient where sex='F')as patientF,(select count(*) from Patient where sex='M') as patientM from anc
e também você pode selecionar e contar tabelas relacionadas como esta
select count(*) as anc,(select count(*) from Patient where Patient.Id=anc.PatientId)as patientF,(select count(*) from Patient where sex='M') as patientM from anc
fonte