colunas com subquery SQL

SQL Server

SQL

Banco de Dados

11/12/2023

Estou fazendo um relatório SQL seguindo esse código:
select 
	YEAR (t.data) 'ANO', 
	MONTH(T.DATA) 'MÊS', 
	o.CODVEND1 'CODIGO VENDEDOR',
	v.VENDEDOR 'NOME VENDEDOR',
	p.CODGRUP 'GRUPO PRODUTO',
	g.DESCRICAO 'DESCRICAO GRUPO',
	o.CODPROD 'CODIGO PRODUTO',
	p.DESCPROD 'DESCRICAO PRODUTO',
	p.CODUNID 'CODIGO UNIDADE',
	u.DESCRICAO 'DESCRICAO UNIDADE',
	o.QTDADE 'QUANTIDADE',
	t.CODCLIFOR 'CODIGO CLIENTE',
	c.NOME 'NOME CLIENTE',
	t.CODTRANSACAO 'CODIGO TRANSACAO',
	t.NOTA 'NF-E', 
	o.CODNATU 'CFOP',
		
	(	SELECT i.CONTA
		FROM INTCONTABIL i
		WHERE i.CODGRUP = p.CODGRUP and i.VARIAVEL='GRC'  
	) as CONTA,


	case when o.CODNATU  in ('1201','2201') then ROUND (s.CUSTOMEDIO * o.QTDADE,2 ) * -1 
	else ROUND (s.CUSTOMEDIO * o.QTDADE,2 )
	end 'VALOR CPV'

from ORDTRANS O inner join TRANSACAO T on o.codtransacao=t.codtransacao
inner join PRODUTO P on o.codprod=p.CODPROD
inner join UNIDADE U on u.CODUNID=p.CODUNID
inner join CLIFOR C on c.CODCLIFOR=t.CODCLIFOR
inner join ORDSALDO S on s.CODORDTRANS=o.CODORDTRANS
INNER JOIN GRUPPROD G on g.CODGRUP=p.CODGRUP
left join V_VENDEDOR V on v.CODVEND1=o.CODVEND1



where t.DATA  between '01/01/2023' and '30/11/2023'
AND t.SITUACAO=3
AND o.CODNATU in ('1201', '2201','5101', '5101A', '5101C', '5101P', '5102', '5116', '5124', '5125','6116', '6101P')

order by t.NOTA


Nessa parte, está trazendo o código da conta que foi realizado o lançamento da despesa:
(	SELECT i.CONTA
		FROM INTCONTABIL i
		WHERE i.CODGRUP = p.CODGRUP and i.VARIAVEL='GRC'  
	) as CONTA,


Preciso pegar esse resultado (codigo da conta), e unir com a tabela CONTAS para trazer a descrição dessa conta, alguma dica de como posso fazer ?
Mylena

Mylena

Curtidas 0

Melhor post

Emerson Nascimento

Emerson Nascimento

11/12/2023

select
    YEAR (t.data) 'ANO', 
    MONTH(T.DATA) 'MÊS', 
    o.CODVEND1 'CODIGO VENDEDOR',
    v.VENDEDOR 'NOME VENDEDOR',
    p.CODGRUP 'GRUPO PRODUTO',
    g.DESCRICAO 'DESCRICAO GRUPO',
    o.CODPROD 'CODIGO PRODUTO',
    p.DESCPROD 'DESCRICAO PRODUTO',
    p.CODUNID 'CODIGO UNIDADE',
    u.DESCRICAO 'DESCRICAO UNIDADE',
    o.QTDADE 'QUANTIDADE',
    t.CODCLIFOR 'CODIGO CLIENTE',
    c.NOME 'NOME CLIENTE',
    t.CODTRANSACAO 'CODIGO TRANSACAO',
    t.NOTA 'NF-E', 
    o.CODNATU 'CFOP',
    cta.DESCRICAO 'DESCRICAO CONTA',
    case when o.CODNATU  in ('1201','2201') then ROUND (s.CUSTOMEDIO * o.QTDADE,2 ) * -1 
    else ROUND (s.CUSTOMEDIO * o.QTDADE,2 )
    end 'VALOR CPV'
 
from
	ORDTRANS O
inner join
	TRANSACAO T on o.codtransacao=t.codtransacao
inner join
	PRODUTO P on o.codprod=p.CODPROD
inner join
	UNIDADE U on u.CODUNID=p.CODUNID
inner join
	CLIFOR C on c.CODCLIFOR=t.CODCLIFOR
inner join
	ORDSALDO S on s.CODORDTRANS=o.CODORDTRANS
INNER JOIN
	GRUPPROD G on g.CODGRUP=p.CODGRUP
left join
	V_VENDEDOR V on v.CODVEND1=o.CODVEND1
left join
	INTCONTABIL i on i.CODGRUP = p.CODGRUP and i.VARIAVEL='GRC' 
left join
	CONTAS CTA on CTA.CODIGO = i.CONTA -- aqui você faz o relacionamento com a tabela de contas
where
	t.DATA  between '01/01/2023' and '30/11/2023'
	AND t.SITUACAO=3
	AND o.CODNATU in ('1201', '2201','5101', '5101A', '5101C', '5101P', '5102', '5116', '5124', '5125','6116', '6101P')
order by
	t.NOTA
GOSTEI 1

Mais Respostas

Arthur Heinrich

Arthur Heinrich

11/12/2023

Não é possível fazer isso, utilizando um subselect na lista de colunas. Você até pode adicionar outro subselect, para retornar a descrição, mas não seria eficiente.

Partindo do pressuposto que esse subselect sempre retorna o número da conta e sempre retorna apenas 1 valor, já que do contrário daria erro na execução da query, você deve colocar a tabela no from:

select
    YEAR (t.data) 'ANO', 
    MONTH(T.DATA) 'MÊS', 
    o.CODVEND1 'CODIGO VENDEDOR',
    v.VENDEDOR 'NOME VENDEDOR',
    p.CODGRUP 'GRUPO PRODUTO',
    g.DESCRICAO 'DESCRICAO GRUPO',
    o.CODPROD 'CODIGO PRODUTO',
    p.DESCPROD 'DESCRICAO PRODUTO',
    p.CODUNID 'CODIGO UNIDADE',
    u.DESCRICAO 'DESCRICAO UNIDADE',
    o.QTDADE 'QUANTIDADE',
    t.CODCLIFOR 'CODIGO CLIENTE',
    c.NOME 'NOME CLIENTE',
    t.CODTRANSACAO 'CODIGO TRANSACAO',
    t.NOTA 'NF-E', 
    o.CODNATU 'CFOP',

    i.CONTA,
    i.DESCRICAO_CONTA,

    case when o.CODNATU  in ('1201','2201') then ROUND (s.CUSTOMEDIO * o.QTDADE,2 ) * -1 
    else ROUND (s.CUSTOMEDIO * o.QTDADE,2 )
    end 'VALOR CPV'
 
from ORDTRANS O inner join TRANSACAO T on o.codtransacao=t.codtransacao
inner join PRODUTO P on o.codprod=p.CODPROD
inner join UNIDADE U on u.CODUNID=p.CODUNID
inner join CLIFOR C on c.CODCLIFOR=t.CODCLIFOR
inner join ORDSALDO S on s.CODORDTRANS=o.CODORDTRANS
INNER JOIN GRUPPROD G on g.CODGRUP=p.CODGRUP
left join V_VENDEDOR V on v.CODVEND1=o.CODVEND1
inner join INTCONTABIL i on i.CODGRUP = p.CODGRUP and i.VARIAVEL='GRC'
 
where t.DATA  between '01/01/2023' and '30/11/2023'
AND t.SITUACAO=3
AND o.CODNATU in ('1201', '2201','5101', '5101A', '5101C', '5101P', '5102', '5116', '5124', '5125','6116', '6101P')
 
order by t.NOTA


Caso a conta não seja retornada sempre, para não eliminar a linha do resultado e simplesmente retornar NULL nas colunas CONTA e DESCRIÇÃO, altere o "inner join" para "left join".
GOSTEI 0
Mylena

Mylena

11/12/2023

Entendi, o problema é que preciso mostrar a descrição de acordo com a conta que retornou nessa subquery.

Exemplo nas contas que retornaram da subquery:

NF-E | CFOP | CONTA | DESCRICAO
1050 | 5101P | 40101020025 | NULL
1050 | 5101P | 40101020015 | NULL
1050 | 5101P | 40101020025 | NULL
1050 | 5101P | 40101020015 | NULL
1050 | 5101P | 40101020025 | NULL


De acordo com cada Conta que retornou preciso unir com a tabela CONTAS para conseguir buscar a descrição da conta.

Exemplo da tabela conta:

CODCONTA | CODBANCO |DESCRICAO
40101020015 | NULL | CPV AVES
40101020016 | NULL | CPV SUINOS
40101020017 | NULL | CPV EQUINOS
40101020018 | NULL | CPV PREMIX
40101020019 | NULL | CPV SM MISTURA
40101020020 | NULL | CPV SM PRONTO USO
40101020021 | NULL | CPV SM PROTEICO
40101020022 | NULL | CPV SM COM UREIA
40101020023 | NULL | CPV NUCLEO
40101020024 | NULL | CPV CONCENTRADO
40101020025 | NULL | CPV ESPECIALIDADES

Resultado esperado:

NF-E | CFOP | CONTA | DESCRICAO
1050 | 5101P | 40101020025 | CPV ESPECIALIDADES
1050 | 5101P | 40101020015 | CPV AVES
1050 | 5101P | 40101020025 | CPV ESPECIALIDADES
1050 | 5101P | 40101020015 | CPV AVES
1050 | 5101P | 40101020025 | CPV ESPECIALIDADES

GOSTEI 0
Mylena

Mylena

11/12/2023

Trouxe o código da conta normal, mas não trouxe a descrição da conta.

select
    YEAR (t.data) 'ANO', 
    MONTH(T.DATA) 'MÊS', 
    o.CODVEND1 'CODIGO VENDEDOR',
    v.VENDEDOR 'NOME VENDEDOR',
    p.CODGRUP 'GRUPO PRODUTO',
    g.DESCRICAO 'DESCRICAO GRUPO',
    o.CODPROD 'CODIGO PRODUTO',
    p.DESCPROD 'DESCRICAO PRODUTO',
    p.CODUNID 'CODIGO UNIDADE',
    u.DESCRICAO 'DESCRICAO UNIDADE',
    o.QTDADE 'QUANTIDADE',
    t.CODCLIFOR 'CODIGO CLIENTE',
    c.NOME 'NOME CLIENTE',
    t.CODTRANSACAO 'CODIGO TRANSACAO',
    t.NOTA 'NF-E', 
    o.CODNATU 'CFOP',
    i.CONTA,
    CTA.DESCRICAO,
 
    case when o.CODNATU  in ('1201','2201') then ROUND (s.CUSTOMEDIO * o.QTDADE,2 ) * -1 
    else ROUND (s.CUSTOMEDIO * o.QTDADE,2 )
    end 'VALOR CPV'
  
from ORDTRANS O inner join TRANSACAO T on o.codtransacao=t.codtransacao
inner join PRODUTO P on o.codprod=p.CODPROD
inner join UNIDADE U on u.CODUNID=p.CODUNID
inner join CLIFOR C on c.CODCLIFOR=t.CODCLIFOR
inner join ORDSALDO S on s.CODORDTRANS=o.CODORDTRANS
INNER JOIN GRUPPROD G on g.CODGRUP=p.CODGRUP
left join V_VENDEDOR V on v.CODVEND1=o.CODVEND1
left join
    INTCONTABIL i on i.CODGRUP = p.CODGRUP and i.VARIAVEL='GRC'
left join
    CONTA CTA on CTA.CONTA = i.CONTA -- aqui você faz o relacionamento com a tabela de contas
  
where t.DATA  between '01/01/2023' and '30/11/2023'
AND t.SITUACAO=3
AND o.CODNATU in ('1201', '2201','5101', '5101A', '5101C', '5101P', '5102', '5116', '5124', '5125','6116', '6101P')
  
order by t.NOTA
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

11/12/2023


Mylena, não conheço a modelagem do teu banco de dados, logo não sei como fazer o relacionamento entre as tabelas.
o trecho com o relacionamento é uma sugestão
left join
    CONTA CTA on CTA.CONTA = i.CONTA -- aqui você faz o relacionamento com a tabela de contas
mas pode não estar correto.
GOSTEI 0
Mylena

Mylena

11/12/2023

Emerson, entendi a logica aqui e vi o que estava errado. Eu estava pensando só em subquery e nem foi necessário para esse caso. Mas deu certo aqui, muito obrigada pela ajuda.
GOSTEI 0
POSTAR