Como Fazer um ORDER BY em uma LIST no Firebird

Firebird é um sistema de banco de dados relacional poderoso e bastante utilizado em várias aplicações. Porém, muitos desenvolvedores podem se deparar com uma limitação ao usar a função LIST, que concatena valores em uma única linha. Especificamente, a dificuldade surge ao tentar ordenar os resultados antes de concatená-los.
Neste post, vamos abordar como realizar um ORDER BY em uma LIST e fornecer um exemplo prático para te ajudar a resolver esse problema.
O Problema
Suponha que você tenha uma tabela de produtos e uma tabela de composição de produtos. Você deseja listar os componentes de um produto específico (por exemplo, código 838), mas quer que esses componentes apareçam em ordem alfabética pela descrição. Um exemplo de consulta seria:
select list(p.descricao, ', ') from produto_composicao p where p.cod_prod = 838
No entanto, se você tentar adicionar um ORDER BY p.descricao diretamente, o Firebird vai gerar um erro, pois não é possível aplicar o ORDER BY diretamente dentro de uma função agregada como LIST.
A Solução: Usar Subquery
Para contornar essa limitação, você pode utilizar uma subconsulta que faz o ORDER BY antes de passar os resultados para a função LIST. Aqui está como o código ficaria:
select list(sub.descricao, ', ') as descricao_composicao from ( select p.descricao from produto_composicao p where p.cod_prod = 838 order by p.descricao ) sub
Explicação do Código
- Subquery: Nós criamos uma subconsulta (aliás
sub) que retorna os resultados já ordenados pela colunap.descricao. - Função
LIST: A funçãoLISTé aplicada sobre os resultados ordenados da subconsulta, garantindo que os dados concatenados estejam em ordem alfabética. - Resultado: A consulta retorna uma única linha contendo a lista de descrições separadas por vírgula, com os itens já ordenados.
Por que Isso Funciona?
No Firebird, funções agregadas como LIST, AVG, SUM, etc., não permitem a inclusão de um ORDER BY diretamente. A solução com a subconsulta resolve o problema, pois o ORDER BY é aplicado antes da agregação. Isso garante que os dados estejam na ordem desejada quando são concatenados.
Conclusão
Se você está trabalhando com o Firebird e precisa ordenar os dados dentro de uma lista concatenada, o uso de subqueries é a solução ideal. Este método é simples e eficaz para garantir que os dados concatenados estejam ordenados da maneira que você precisa.
Agora, você pode aplicar essa técnica sempre que precisar ordenar os dados em uma lista no Firebird!
Gostou do artigo? Ficou com alguma dúvida ou tem outra dica para ordenar listas no Firebird? Deixe seu comentário abaixo! Sua participação é muito importante para nós, e será um prazer ajudar ou aprender algo novo com você. Vamos continuar essa conversa e compartilhar conhecimento!
Um abraço e até o próximo post. Valeu!
#Firebird
#SQL
#BancoDeDados
#Ordenação
#List
#GiovaniDaCruz
3 comentários
-
-
Oi Jefferson, talvez fazendo algo assim:
SELECT
Ano,
LIST(Mes, ',') AS Meses,
LIST(Total, ',') AS Totais
FROM (
SELECT
EXTRACT(YEAR FROM DataVenda) AS Ano,
LPAD(EXTRACT(MONTH FROM DataVenda), 2, '0') AS Mes,
SUM(ValorVenda) AS Total
FROM
Vendas
GROUP BY
EXTRACT(YEAR FROM DataVenda),
EXTRACT(MONTH FROM DataVenda)
ORDER BY
EXTRACT(YEAR FROM DataVenda),
EXTRACT(MONTH FROM DataVenda)
) AS Ordenado
GROUP BY
Ano;Se ainda não funcionar, tens como colocar aqui nos comentários o metadata da sua tabela e alguns inserts?
Que ai poderei fazer mais testes
-
Olá, Giovani tudo bom
Você pode entrar em contato comigo neste e-mail do cadastro?
-
-
Exemplo bem simples, vamos para um caso mais complexo:
Tenho um SQL que irá listar o total de venda por mês e ano, porém, preciso que o mês e o total seja mostrado em lista utilizando o LIST e o ano seja um campo de agrupamento, ou seja, resultado final da seguinte forma:
Ano | Mes | Total
2023 | 01,02,03,04,05,06,07,08,09,10,11,12 | 50.25,.47.50,51,54.75
2024 | 01,02,03,04,05,06,07,08,09,10,11,12 | 50.25,.47.50,51,54.75
Porém, ao utilizar o LIST com group by no ANO, é perdido a ordenação dos meses, não seguindo a ordem correta de 01, 02, 03 etc.. Sabe como contornar isso com SQL? Firebird 3.0