Como selecionar todos os RECNOs em uma query com GROUP BY

No artigo de hoje, vou demonstrar como selecionar informações em uma coluna de query usando FOR XML PATH.

Recentemente um aluno me perguntou, se tinha como ele conferir os valores que estavam agrupados de uma query, analisando quais dados que estavam entrando dentro do agrupamento.

Para fazer isso, nós devemos utilizar o conceito do FOR XML PATH, onde basicamente nós selecionamos várias linhas, que se transformam em uma única linha de informação.

Então, apenas para exemplificar no nosso exemplo, a lógica seria assim:

  1. Primeiro fazemos a query buscando todos os grupos de produto (SBM)
  2. Depois adicionamos um join com os produtos (SB1)
  3. Após fazer a junção, nós agrupamos por grupo, e mostramos quantos produtos existem (COUNT)
  4. Por último, adicionamos uma subquery buscando os Recnos dos Produtos, com o mesmo filtro usado no join (SELECT com FOR XML PATH). No nosso caso, nós selecionamos até 800 caracteres, mas você pode aumentar esse limite

Obs.: No passo 4, você pode usar outros campos ao invés do Recno se achar mais fácil, como por exemplo, código do produto

Abaixo um print de resultado da query:

Exemplo dos Recnos dos produtos na quarta coluna

E abaixo a query SQL:

SELECT
	BM_GRUPO,
	BM_DESC,
	COUNT(B1_COD) AS QTD_PRODS,
	ISNULL(
        CONVERT(VARCHAR(800), 
            (
                SELECT
                    CONVERT(VARCHAR, SB1B.R_E_C_N_O_) + ', '
                FROM
                    SB1990 SB1B
                WHERE
                    SB1B.B1_FILIAL = ''
					AND SB1B.B1_GRUPO = SBM.BM_GRUPO
					AND SB1B.D_E_L_E_T_ = ''
                ORDER BY
                    SB1B.R_E_C_N_O_
                FOR XML PATH ('')
            )
        ), 
    '') AS LIST_REC
FROM
	SBM990 SBM
	LEFT JOIN SB1990 SB1 ON (
		B1_FILIAL = ''
		AND B1_GRUPO = BM_GRUPO
		AND SB1.D_E_L_E_T_ = ' '
	)
WHERE
	BM_FILIAL = '01'
	AND SBM.D_E_L_E_T_ = ' '
GROUP BY
	BM_GRUPO,
	BM_DESC
ORDER BY
	QTD_PRODS DESC

Bom pessoal, por hoje é só.

Abraços e até a próxima.

Dan Atilio (Daniel Atilio)
Especialista em Engenharia de Software pela FIB. Entusiasta de soluções Open Source. E blogueiro nas horas vagas.

4 Responses

  1. MARCOS BISPO ABRAHAO disse:

    Parabéns Daniel, por compartilhar esta dica valiosa!!

  2. Walter Franco disse:

    Bom dia Daniel,
    Acompanho sempre suas dicas e como o parceiro aí disse, são sempre valiosas…
    Esta função é válida para o BD SQL Server? Você sabe me dizer se no Oracle tem algo compatível?
    Obrigado

Deixe uma resposta