A ordenação de um conjunto de linhas pode necessitar de um critério de desempate principalmente nos casos onde é necessário obter a posição relativa de cada linha no resultado final de um relatório. Neste artigo veremos alguns exemplos de como aplicar critérios de desempate utilizando a cláusula ORDER BY de uma instrução SELECT para identificar cada linha do resultado de acordo com a ordem desejada e o critério de desempate.

Campeão da Taça

Como dito na introdução do artigo, o critério de desempate geralmente é baseado em algum atributo da tabela. Em algumas situações somente os atributos não são suficientes para o critério de desempate e precisamos montar alguma expressão que represente o critério de desempate na nossa instrução SELECT. O próximo exemplo que veremos é um caso típico deste tipo de critério de desempate.

Em um campeonato de futebol diversos times disputam partidas entre si, de alguma maneira lógica, com o objetivo de conquistar a taça do campeonato, dada ao time que mais conseguir pontos em sua campanha. Além da quantidade de pontos que cada time obtém, a tabela de colocação no campeonato armazena os gols a favor e os gols contra, como pode ser visto nos dados que a Tabela 3 apresenta.

Times do campeonato
Tabela 3. Times do campeonato

O critério de desempate deste campeonato diz que, quando dois ou mais times possuírem a mesma pontuação, deve-se aplicar o saldo de gols como critério de desempate. Este saldo de gols é obtido subtraindo a quantidade de gols contra da quantidade de gols a favor do time em questão. Aquele que possuir o maior saldo de gols deve ser posicionado acima dos outros times com a mesma pontuação.

Para obter a tabela deste campeonato com as colocações de cada time devemos listar as linhas ordenando-as pela quantidade decrescente de pontos e pelo saldo. Em uma instrução SELECT é simples montar a expressão que gera o saldo de gols como uma coluna calculada. Podemos utilizar o nome da coluna calculada na cláusula ORDER BY, facilitando a leitura da instrução SQL. A Listagem 2 mostra a instrução SELECT que ordena os dados corretamente.

Instrução que retorna os times do campeonato ordenados
Listagem 2. Instrução que retorna os times do campeonato ordenados

De acordo com os dados da Tabela 3, o time ‘SOLTEIROS LTDA’ leva a taça do campeonato para a casa, pois possui a maior quantidade de pontos. Para escolher o vice-campeão devemos aplicar o critério de desempate entre os times ‘S. D. PÉ E BOLA’ e ‘UNIDOS F.C.’, onde o primeiro leva a melhor devido ao seu saldo de gols, como os dados da Tabela 4 mostram.

sql-25-07-2008pic18.JPG
Tabela 4. Tabela de colocação final do campeonato

Ordenando o Telemarketing

No último exemplo que veremos o critério de desempate depende não somente dos atributos, mas sim na correlação entre seus valores. Valores estes que, dependendo da situação, precisam ser modificados para facilitar a ordenação.

Em um modelo de telemarketing passivo diversos operadores (ou operadoras) possuem um telefone conectado a uma central de atendimento telefônico. Para cada operador é designado o número da sua posição de atendimento (P.A.) e, conforme as ligações vão chegando, a central deve seguir uma ordem de atendimento que indica quais PA.’s vão receber as ligações. Esta ordem é baseada em três critérios:

  1. A prioridade das P.A. As prioridades são: Alta (A), Normal (N) e Baixa (B) e as chamadas devem ser encaminhadas nesta ordem de prioridades.
  2. O Status da P.A. Status válidos são: Livre (L), Ocupado (O) e Inoperante (I). As P.A.’s que tenham os status Ocupado e Inoperante não recebem ligações, mas as que têm o status Livre recebem ligações.
  3. Tempo desde a última ligação. O tempo desde que a P.A. atendeu a sua última ligação. Este tempo é armazenado em segundos e a P.A. que estiver mais tempo sem atender uma ligação tem prioridade sobre as outras.

A tabela que armazena o estado atual do telemarketing é mostrada na Tabela 5, onde temos uma configuração válida dos operadores.

sql-25-07-2008pic19.JPG
Tabela 5. Estado do telemarketing

O que o sistema deve gerar é, dado uma determinada configuração dos operadores e as regras de atendimento, a ordem das P.A.’s que vão atender as próximas ligações.

Para determinar qual é a próxima P.A. que vai atender a ligação temos que seguir a mesma ideia apresentada nos dois exemplos anteriores: aplicar a regra de ordenação e o critério de desempate na instrução SELECT.

O primeiro critério da ordem de atendimento diz respeito às prioridades, que podem assumir os valores Alta, Normal ou Baixa, representados na coluna PRIORIDADE através dos caracteres ‘A’,’N’, e ‘B’, respectivamente. Com estes caracteres representando as prioridades não conseguiremos utilizar a coluna PRIORIDADE para ordenar os dados. Para resolver este problema vamos transformar os caracteres que representam a prioridade em números. Esta transformação será feita atribuindo o valor 1 para prioridade Alta, 2 para Normal e 3 para Baixa. Vamos criar uma view que gera uma coluna calculada com os novos valores da coluna PRIORIDADE utilizando a estrutura CASE.

O próximo critério da ordem de atendimento diz respeito ao Status da P.A. Este critério diz que apenas o status ‘L’, de Livre, pode atender ligações. O que temos a fazer é filtrar os registros da tabela para que somente aqueles com o valor ‘L’ na coluna STATUS sejam mostrados no nosso relatório.

O último critério diz respeito ao tempo que passou desde a última ligação atendida por uma determinada PA. Como o valor do tempo decorrido está sem segundos basta ordenar o valor desta coluna de forma decrescente.

A Listagem 3 apresenta a criação da view que gera uma coluna calculada a partir dos valores da coluna PRIORIDADE e a instrução SELECT que retorna qual é a ordem das P.A’s a ser seguida no atendimento das ligações.

View com a coluna calculada e a instrução que gera a ordem das P.A.’s
Listagem 3. View com a coluna calculada e a instrução que gera a ordem das P.A.’s

Analisando o estado do telemarketing apresentado na Tabela 5 e aplicando as regras de prioridade podemos perceber que as P.A.’s 5 e 6 possuem prioridade Alta e, portanto, deveriam atender a próxima ligação. A P.A. 6 está ocupada o que faz com que a P.A 5 seja a primeira da fila a atender a próxima ligação. As P.A.’s 3 e 4 possuem a prioridade Normal e a P.A. 4 está inoperante, fazendo com que a P.A. 3 seja a próxima da fila . As duas P.A.’s de prioridade baixa estão livres para atender, mas a P.A. 2 está a mais tempo na espera por uma ligação e por isso entra na fila antes da P.A. 1. A ordem final de atendimento, gerada pela instrução SELECT da Listagem 3, é apresentada na Tabela 6.

Ordem de atendimento do telemarketing
Tabela 6. Ordem de atendimento do telemarketing

Notem que se uma P.A. mudar o seu status ou se uma prioridade for modificada na tabela a instrução só precisa ser executada novamente para obtermos a nova ordem de atendimento do telemarketing.

Conclusão

Neste artigo discutimos como implementar regras de desempate em instruções SELECT através da cláusula ORDER BY. Três exemplos diferentes foram apresentados com o objetivo de explicar ao leitor quando devemos modificar a instrução SELECT para atender aos requisitos da regra de desempate que foi especificada.