Tabela #01 Status
:
StatusID Status
-----------------------
1 Opened
2 Closed
3 ReOpened
4 Pending
Tabela #02 Claims
:
ClaimID CompanyName StatusID
--------------------------------------
1 ABC 1
2 ABC 1
3 ABC 2
4 ABC 4
5 XYZ 1
6 XYZ 1
Resultado esperado:
CompanyName TotalOpenClaims TotalClosedClaims TotalReOpenedClaims TotalPendingClaims
--------------------------------------------------------------------------------
ABC 2 1 0 1
XYZ 2 0 0 0
Como eu preciso escrever a consulta para que eu possa obter o resultado conforme o esperado?
É mais fácil com
SUM()
umaCASE
declaração:Essa é uma transformação típica de pivô, e a agregação condicional, como sugerido por Phil , é a boa e velha maneira de implementá-la.
Há também uma sintaxe mais moderna para alcançar o mesmo resultado, que usa a cláusula PIVOT:
Internamente, essa sintaxe aparentemente mais simples é equivalente à consulta GROUP BY de Phil. Mais exatamente, é equivalente a esta variação:
Portanto, uma consulta PIVOT é uma consulta GROUP BY implícita, essencialmente.
As consultas PIVOT, no entanto, são notoriamente mais complicadas de lidar do que as consultas GROUP BY explícitas com agregação condicional. Ao usar o PIVOT, você precisa sempre ter em mente uma coisa:
Claims
neste caso) que não são explicitamente mencionadas na cláusula PIVOT são colunas GROUP BY .Se
Claims
consistir apenas nas três colunas mostradas no seu exemplo, a consulta PIVOT acima funcionará conforme o esperado, pois aparentementeCompanyName
é a única coluna não mencionada explicitamente no PIVOT e, portanto, acaba sendo o único critério do GROUP BY implícito.No entanto, se
Claims
tiver outras colunas (digamos,ClaimDate
), elas serão usadas implicitamente como colunas GROUP BY adicionais – ou seja, sua consulta estará essencialmente fazendoO resultado provavelmente não será o que você deseja.
Isso é fácil de corrigir, no entanto. Para excluir colunas irrelevantes da participação no agrupamento implícito, basta usar uma tabela derivada, onde você selecionará apenas as colunas necessárias para o resultado, embora isso torne a consulta menos elegante:
Ainda assim, se
Claims
já for uma tabela derivada, não há necessidade de adicionar outro nível de aninhamento, apenas certifique-se de que na tabela derivada atual você esteja selecionando apenas as colunas necessárias para produzir a saída.Você pode ler mais sobre PIVOT no manual:
É certo que minha experiência é principalmente com MySQL e não passei muito tempo no SQL Server. Eu ficaria muito surpreso se a seguinte consulta não funcionasse:
Isso não fornece a saída no formato desejado, mas fornece todas as informações desejadas, embora deixando de fora os zeros. Isso parece muito mais simples para mim do que lidar com instruções CASE dentro de uma consulta que parece uma ideia especialmente ruim se estiver sendo usada apenas para formatação.