Usuário com melhor resposta
Dúvida de como criar uma query

Pergunta
-
Prezados, boa tarde! Eu tenho 4 tabelas relacionadas e preciso fazer o somatório de dois campos. Eu pesquisei na internet e não conseguir achar. Por isso venho pedir humildemente uma ajuda.
Vou colocar as tabelas:
Nessa tabela eu tenho todos os contratos encontrados através do cd do Projeto..
Select * From TbContrato Where CdProjeto = 26
Depois com os contratos eu preciso das obras de cada contrato:
Select * From TbObra Where CdContrato = 248
Com as obras eu preciso pegar o último registro dessa outra tabela:
Select Top 1 CdMedicaoContratoAditivo From TbMedicaoContratoAditivo Where CdObraOs = 312 Order by TbMedicaoContratoAditivo.CdMedicaoContratoAditivo Desc
Depois eu preciso pegar os dos valores (PercentualConclusaoContrato, ValorContratoComAditivo) para serem somados
Select PercentualConclusaoContrato, ValorContratoComAditivo From TbMedicaoSequencia Where CdMedicaoContratoAditivo = 807 And Status = 'AP' Order By SequenciaDaMedicao Desc
Alguém poderia ajudar-me por favor?
Obrigado.
Adilson
Respostas
-
Deleted
- Marcado como Resposta Adilson_ASP quinta-feira, 2 de maio de 2013 17:53
Todas as Respostas
-
Boa tarde,
Você pode postar uma amostra de dados dessas tabelas e o respectivo resultado esperado?
Assinatura: http://www.imoveisemexposicao.com.br
-
Gapimex, bom dia!
Então na primeira tabela (Contrato) os dados são:
243 d6c1a32c-ff65-49d5-8a85-0ea4a9bd92b7 NULL 1111 Contrato de teste para ochamado 3445 1 106 1 AN 37 True 01/05/2011 00:00:00 01/11/2011 00:00:00 01/01/2012 00:00:00 31/12/2012 00:00:00 NULL Verifricar o relatorio de andamento NULL NULL NULL NULL NULL NULL 18 NULL NULL NULL NULL False 01/10/2012 10:46:26 01/10/2012 11:56:43 NULL NULL NULL NULL NULL NULL NULL NULL NULL Dados da Tabele OBra:
301 0e1902d3-6ff2-49aa-a043-2d6f62cb53c1 Obra de teste - com valores dobrados Obra 2 de teste - com valores dobrados AN 1 37 243 NULL NULL NULL 18 NULL NULL NULL NULL NULL NULL NULL NULL 2222 01/10/2012 11:25:33 01/10/2012 11:25:33 NULL 01/01/2012 00:00:00 31/12/2012 00:00:00 NULL 106 NULL NULL NULL NULL NULL NULL NULL Os Dados da tabela MedicaoContratoAditivo:
449 758612f1-71f9-4b11-9bcc-e0540e147c7d 274 243 NULL 1 37 301 Orçamento 2 AT 01/10/2012 11:31:43 01/10/2012 11:31:43 48000,0000000000 NULL 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 True True NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
Dados da tabela MedicaoSequencia: Nessa tabelas eu tenho dois campos: PercentualConclusaoContrato e ValorContratoComAditivo Eu preciso fazer a somatória desses dois campos para todos os contratos. Esses valores tem que acumular para cada contrato e Obra.
1317 6fbd97bc-d01b-4be5-bd69-b6e9b55e91a3 460 449 3 01/10/2012 11:44:55 NULL NULL NULL NULL 18000,0000000000 False NULL NULL AP 31/08/2012 00:00:00 01/08/2012 00:00:00 31/08/2012 00:00:00 01/08/2012 00:00:00 6000,0000000000 NULL 12000,0000000000 30000,0000000000 30000,0000000000 01/10/2012 11:44:03 01/10/2012 11:45:06 {"ValorAcumuladoAnterior":12000,"ValorPeriodo":0,"ValorAcumulado":12000,"ValorSaldo":36000,"Status":"CR"} CR 0,0000000000 NO 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 0,0000000000 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 3 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Obrigado pela força.
Eu estou tentando fazer um Fetch dentro do outro mas esta dando erro:
Msg 102, Level 15, State 1, Line 91
Incorrect syntax near 'LOBRAS'. Eu não conheço muito SQlServer.DECLARE @CDCONTRATO INT DECLARE @CDOBRAS INT DECLARE LCONTRATOS CURSOR FOR SELECT CDCONTRATO FROM DBCADU.DBO.TbContrato WHERE CDPROJETO = 26 OPEN LCONTRATOS FETCH NEXT FROM LCONTRATOS INTO @CDCONTRATO WHILE @@FETCH_STATUS = 0 BEGIN --PRINT @CDCONTRATO FETCH NEXT FROM LCONTRATOS --SELECIONA TODAS AS OBRAS DECLARE LOBRAS CURSOR FOR SELECT DISTINCT CDOBRA FROM DBCADU.DBO.TBOBRA WHERE DBCADU.DBO.TBOBRA.CDCONTRATO = @CDCONTRATO FETCH NEXT FROM LOBRAS INT @CDOBRAS WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM LOBRAS END END CLOSE LOBRAS CLOSE LCONTRATOS DEALLOCATE LOBRAS DEALLOCATE LCONTRATOS
Adilson
-
Bom dia
Estou sem um SQL aqui portanto não testei mas o que vc pediu não precisa de um cursor ou loops, basta usar os agrupamentos correto e as sumarizações.
Select TbObra.CdContrato, TbMedicaoContratoAditivo.CdObraOs, TbMedicaoContratoAditivo.CdMedicaoContratoAditivo, SUM(TbMedicaoSequencia.PercentualConclusaoContrato) AS PercentualConclusaoContrato, SUM(TbMedicaoSequencia.ValorContratoComAditivo) AS ValorContratoComAditivo From TbContrato Inner Join TbObra ON (TbObra.CdContrato = TbContrato.CdContrato) Inner Join TbMedicaoContratoAditivo ON (TbMedicaoContratoAditivo.CdObraOs = TbObra.CdObraOs) Inner Join TbMedicaoSequencia ON (TbMedicaoSequencia.CdMedicaoContratoAditivo = TbMedicaoContratoAditivo.CdMedicaoContratoAditivo AND TbMedicaoSequencia.Status = 'AP') Where TbContrato.CdProjeto = 26 Group by TbObra.CdContrato, TbMedicaoContratoAditivo.CdObraOs, TbMedicaoContratoAditivo.CdMedicaoContratoAditivo Having TbMedicaoContratoAditivo.CdMedicaoContratoAditivo = MAX(TbMedicaoContratoAditivo.CdMedicaoContratoAditivo)
Att,
Tiago -
-
Conseguir fazer dessa forma:
DECLARE @CDCONTRATO INT DECLARE @CDOBRAS INT DECLARE @CDMEDICAOCONTRATOADITIVO INT DECLARE @VALORCONTRATOCOMADITIVO DECIMAL(25,10),@PERCENTUACONCLUSAOCONTRATO DECIMAL(25,10) DECLARE @ACUMULAVALORCONTRATOCOMADITIVO DECIMAL(25,10),@ACUMULAPERCENTUACONCLUSAOCONTRATO DECIMAL(25,10) DECLARE LCONTRATOS CURSOR FOR SELECT CDCONTRATO FROM DBCADU.DBO.TbContrato WHERE CDPROJETO = 26 SET @ACUMULAVALORCONTRATOCOMADITIVO = 0 SET @ACUMULAPERCENTUACONCLUSAOCONTRATO = 0 OPEN LCONTRATOS FETCH NEXT FROM LCONTRATOS INTO @CDCONTRATO WHILE @@FETCH_STATUS = 0 BEGIN --SELECIONA TODAS AS OBRAS DECLARE LOBRAS CURSOR FOR SELECT DISTINCT CDOBRA FROM DBCADU.DBO.TBOBRA WHERE DBCADU.DBO.TBOBRA.CDCONTRATO = @CDCONTRATO OPEN LOBRAS FETCH NEXT FROM LOBRAS INTO @CDOBRAS WHILE @@FETCH_STATUS = 0 BEGIN SET @CDMEDICAOCONTRATOADITIVO =(Select Top 1 CdMedicaoContratoAditivo From TbMedicaoContratoAditivo Where CdObraOs = @CDOBRAS Order by TbMedicaoContratoAditivo.CdMedicaoContratoAditivo Desc) SET @VALORCONTRATOCOMADITIVO = (Select Top 1 ValorContratoComAditivo From TbMedicaoSequencia Where CdMedicaoContratoAditivo = @CDMEDICAOCONTRATOADITIVO And Status = 'AP' Order By SequenciaDaMedicao Desc) SET @PERCENTUACONCLUSAOCONTRATO = (Select Top 1 PercentualConclusaoContrato From TbMedicaoSequencia Where CdMedicaoContratoAditivo = @CDMEDICAOCONTRATOADITIVO And Status = 'AP' Order By SequenciaDaMedicao Desc) FETCH NEXT FROM LOBRAS INTO @CDOBRAS END SET @ACUMULAVALORCONTRATOCOMADITIVO = @ACUMULAVALORCONTRATOCOMADITIVO + @VALORCONTRATOCOMADITIVO SET @ACUMULAPERCENTUACONCLUSAOCONTRATO = @ACUMULAPERCENTUACONCLUSAOCONTRATO + @PERCENTUACONCLUSAOCONTRATO CLOSE LOBRAS DEALLOCATE LOBRAS FETCH NEXT FROM LCONTRATOS INTO @CDCONTRATO END CLOSE LCONTRATOS DEALLOCATE LCONTRATOS SELECT @ACUMULAVALORCONTRATOCOMADITIVO AS ValorTotal,@ACUMULAPERCENTUACONCLUSAOCONTRATO as PercentualTotal
Não sei se é a melhor forma.
Adilson
-
Cursores são muito caro, devem ser usado com cuidado, se você tiver muitos dados nas tabelas isso pode demorar muito.
Seu problema pode ser resolvido com uma unica query apenas relacionando as tabelas e agrupando os dados.
Você testou meu exemplo?
Att,
Tiago -
Oi TiagoR, desculpe a demora em responder. Eu testei o seu exemplo e ele trouxe todas as MedicoesContratoAditivo. Eu preciso que ele traga somente a última. Por isso eu relacionei com a Obra. Pois através da obra eu consigo pegar o último valor.
Me tira uma dúvida. No exemplo que eu fiz com cursor, eu tenho 201 contratos. Porém não vem o valor. Quando tem menos ai da certo. Saberia me informar o problema?
Adilson
Eduardo veja como estão vindo:
CdContrato CdObaOs CdMedicaoContratoAditivo PercentualConcluaoContrato ValorContratoComAditivo 192 206 301 37.148 313.292.491.200.000.000 192 206 398 286.253 835.446.643.200.000.000 248 314 532 0.0845 4.505.623.069.300.000.000 248 312 533 0.3681 4.505.623.069.300.000.000 248 313 534 0.0604 4.505.623.069.300.000.000 248 314 535 31.833 36.044.984.554.400.000.000 248 312 541 197.741 54.067.476.831.600.000.000 248 313 553 32.468 54.067.476.831.600.000.000 248 314 581 26.252 18.022.492.277.200.000.000 248 312 807 18.404 4.505.623.069.300.000.000 248 314 809 0.6761 4.505.623.069.300.000.000 248 313 810 0.3022 4.505.623.069.300.000.000
- Editado Adilson_ASP terça-feira, 30 de abril de 2013 17:08
-
-
José boa tarde! Obrigado pela força.
Eu rodei o seu código e deu o seguinte erro:
Msg 139, Level 15, State 1, Line 0
Cannot assign a default value to a local variable.
Msg 137, Level 15, State 2, Line 81
Must declare the scalar variable "@xCdProjeto".Adilson
-
-
-
Talvez existam outras opções melhores, mas segue um script para teste:
with CTE_M as ( select c.CdContrato, o.CdObra, m.CdMedicaoContratoAditivo, ROW_NUMBER() OVER (PARTITION BY c.CdContrato, o.CdObra ORDER BY m.CdMedicaoContratoAditivo DESC) as RowNum from TbContrato as c inner join TbObra as o on o.CdContrato = c.CdContrato inner join TbMedicaoContratoAditivo as m on m.CdObraOs = o.CdObra where c.CdProjeto = 26 ), CTE_S as ( select c.CdContrato, c.CdObra, c.CdMedicaoContratoAditivo, s.PercentualConclusaoContrato, s.ValorContratoComAditivo, ROW_NUMBER() OVER (PARTITION BY c.CdContrato, c.CdObra, c.CdMedicaoContratoAditivo ORDER BY s.SequenciaDaMedicao DESC) as RowNum from CTE_M as c inner join TbMedicaoSequencia as s on s.CdMedicaoContratoAditivo = c.CdMedicaoContratoAditivo and s.Status = 'AP' where c.RowNum = 1 ) select CdContrato, CdObra, CdMedicaoContratoAditivo, sum(PercentualConclusaoContrato) as PercentualConclusaoContrato, sum(ValorContratoComAditivo) as ValorContratoComAditivo from CTE_S where RowNum = 1 group by CdContrato, CdObra, CdMedicaoContratoAditivo
Espero que seja útil.Assinatura: http://www.imoveisemexposicao.com.br
-
-
gapimex, boa tarde.
Do jeito que você passou deu certo. Porém ele não está somando os resultado. dos campos Percentual Valor. Ele está trazendo do jeito que está no banco. Mas de resto deu certo. Será qued falta mais alguma coisa?
Obrigado pela ajuda.
Adilson
-
Boa tarde,
Não sei se entendi corretamente o seu objetivo, mas experimente dessa forma:
with CTE_M as ( select c.CdContrato, o.CdObra, m.CdMedicaoContratoAditivo, ROW_NUMBER() OVER (PARTITION BY c.CdContrato, o.CdObra ORDER BY m.CdMedicaoContratoAditivo DESC) as RowNum from TbContrato as c inner join TbObra as o on o.CdContrato = c.CdContrato inner join TbMedicaoContratoAditivo as m on m.CdObraOs = o.CdObra where c.CdProjeto = 26 ) select c.CdContrato, c.CdObra, c.CdMedicaoContratoAditivo, sum(s.PercentualConclusaoContrato) as PercentualConclusaoContrato, sum(s.ValorContratoComAditivo) as ValorContratoComAditivo from CTE_M as c inner join TbMedicaoSequencia as s on s.CdMedicaoContratoAditivo = c.CdMedicaoContratoAditivo where c.RowNum = 1 and s.Status = 'AP' group by c.CdContrato, c.CdObra, c.CdMedicaoContratoAditivo
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
-
Então o código que você me ajudou está retornando da seguinte maneira os dados:
CdContrato CdObra CdMedicaoContratoAditivo PercentualConclusaoContrato ValorContratoComAditivo 248 313 810 0.3022 4.505.623.069.300.000.000 192 206 398 164.767 104.430.830.400.000.000 248 314 809 0.6761 4.505.623.069.300.000.000 248 312 807 18.404 4.505.623.069.300.000.000 Na coluna PercentualConclusaoContrato ele teriq que somar todas as linha. E com a coluna ValorContratoComAditivo ele treria que somar o cdContrato = 192(104.430.830.400.000.000) + o cdContrato = 248(4.505.623.069.300.000.000). Somente. Isso serviria se tivesse mais contratos. Pois se tiver mais obra o valor do contrato será o mesmo.
Obrigado pela ajuda e desculpe o incomodo.
Adilson
- Editado Adilson_ASP terça-feira, 30 de abril de 2013 19:42
-
-
Não consegui entender o resultado que você quer obter... experimente executar o script abaixo e diga por favor qual deveria ser o resultado retornado:
declare @TbContrato table (CdContrato int, CdProjeto int); insert into @TbContrato values (1, 26), (2, 26); declare @TbObra table (CdObra int, CdContrato int); insert into @TbObra values (101, 1), (102, 1), (201, 2), (202, 2); declare @TbMedicaoContratoAditivo table (CdObraOs int, CdMedicaoContratoAditivo int); insert into @TbMedicaoContratoAditivo values (101, 1011), (101, 1012), (102, 1021), (102, 1022), (201, 2011), (201, 2012), (202, 2021), (202, 2022); declare @TbMedicaoSequencia table (CdMedicaoContratoAditivo int, PercentualConclusaoContrato float, ValorContratoComAditivo money, Status char(2)); insert into @TbMedicaoSequencia values (1011, 11, 1000, 'AP'), (1011, 12, 100, 'AP'), (1012, 13, 1025, 'AP'), (1012, 14, 125, 'AP'), (1021, 21, 1000, 'AP'), (1021, 22, 1001, 'AP'), (1022, 23, 2000, 'AP'), (1022, 24, 2002, 'AP'), (2011, 16, 3000, 'AP'), (2011, 17, 3003, 'AP'), (2012, 18, 4000, 'AP'), (2012, 19, 4004, 'AP'), (2021, 26, 5000, 'AP'), (2021, 27, 5005, 'AP'), (2022, 28, 6000, 'AP'), (2022, 29, 6006, 'AP'); with CTE_M as ( select c.CdContrato, o.CdObra, m.CdMedicaoContratoAditivo, ROW_NUMBER() OVER (PARTITION BY c.CdContrato, o.CdObra ORDER BY m.CdMedicaoContratoAditivo DESC) as RowNum from @TbContrato as c inner join @TbObra as o on o.CdContrato = c.CdContrato inner join @TbMedicaoContratoAditivo as m on m.CdObraOs = o.CdObra where c.CdProjeto = 26 ) select c.CdContrato, c.CdObra, c.CdMedicaoContratoAditivo, sum(s.PercentualConclusaoContrato) as PercentualConclusaoContrato, sum(s.ValorContratoComAditivo) as ValorContratoComAditivo from CTE_M as c inner join @TbMedicaoSequencia as s on s.CdMedicaoContratoAditivo = c.CdMedicaoContratoAditivo where c.RowNum = 1 and s.Status = 'AP' group by c.CdContrato, c.CdObra, c.CdMedicaoContratoAditivo
Assinatura: http://www.imoveisemexposicao.com.br
-
Então o resultado tem que ser esse:
PercentualConclusaoContrato ValorContratoComAditivo
184,15 4.610.053.899.700.000.000
Esse resultado acima é a somatório dos resultado abaixo.
184,15 = 0.3022+164.767+0.6761+18.404 = Coluna PercentualConclusaoContrato
4.610.053.899.700.000.000 = 4.505.623.069.300.000.000 + 104.430.830.400.000.000 = Coluna ValorContratoComAditivo
CdContrato CdObra CdMedicaoContratoAditivo PercentualConclusaoContrato ValorContratoComAditivo 248 313 810 0.3022 4.505.623.069.300.000.000 192 206 398 164.767 104.430.830.400.000.000 248 314 809 0.6761 4.505.623.069.300.000.000 248 312 807 18.404 4.505.623.069.300.000.000 Obrigado.Adilson
-
Uma pequena alteração, ultilizando Sub Selects.
Select TbObra.CdContrato, TbMedicaoContratoAditivo.CdObraOs, TbMedicaoContratoAditivo.CdMedicaoContratoAditivo, SUM(TbMedicaoSequencia.PercentualConclusaoContrato) AS PercentualConclusaoContrato, SUM(TbMedicaoSequencia.ValorContratoComAditivo) AS ValorContratoComAditivo From TbContrato Inner Join TbObra ON (TbObra.CdContrato = TbContrato.CdContrato) Inner Join TbMedicaoContratoAditivo as tMc1 ON (tMc1.CdObraOs = TbObra.CdObraOs AND TbMedicaoContratoAditivo.CdMedicaoContratoAditivo = (select MAX(tMc2.CdMedicaoContratoAditivo) from TbMedicaoContratoAditivo as tMc2 where tMc2.CdObraOs = tMc1.CdObraOs Group By CdObraOs)) Inner Join TbMedicaoSequencia ON (TbMedicaoSequencia.CdMedicaoContratoAditivo = TbMedicaoContratoAditivo.CdMedicaoContratoAditivo AND TbMedicaoSequencia.Status = 'AP') Where TbContrato.CdProjeto = 26 Group by TbObra.CdContrato, TbMedicaoContratoAditivo.CdObraOs, TbMedicaoContratoAditivo.CdMedicaoContratoAditivo
Funciona?
-
Adilson,
Para facilitar o entendimento da questão acho que seria melhor você postar qual deveria ser o resultado considerando os valores do script que postei acima.
Você pode executa-lo através do SQL Server Management Studio, basta copiar e colar dentro da janela "Nova Consulta".
Assinatura: http://www.imoveisemexposicao.com.br
-
-
Experimente dessa forma:
with CTE_M as ( select c.CdContrato, o.CdObra, m.CdMedicaoContratoAditivo, ROW_NUMBER() OVER (PARTITION BY c.CdContrato, o.CdObra ORDER BY m.CdMedicaoContratoAditivo DESC) as RowNumAd, ROW_NUMBER() OVER (PARTITION BY c.CdContrato ORDER BY o.CdObra DESC) as RowNumOb from TbContrato as c inner join TbObra as o on o.CdContrato = c.CdContrato inner join TbMedicaoContratoAditivo as m on m.CdObraOs = o.CdObra where c.CdProjeto = 26 ) select sum(s.PercentualConclusaoContrato) as PercentualConclusaoContrato, sum(case when c.RowNumOb = 1 then s.ValorContratoComAditivo else 0 end) as ValorContratoComAditivo from CTE_M as c inner join TbMedicaoSequencia as s on s.CdMedicaoContratoAditivo = c.CdMedicaoContratoAditivo where c.RowNumAd = 1 and s.Status = 'AP'
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
-
Deleted
- Marcado como Resposta Adilson_ASP quinta-feira, 2 de maio de 2013 17:53
-
Jose, bom dia!
Mais uma vez obrigado pela ajuda. A primeira parte é isso mesmo está perfeita. A segunda parte ele não está vindo certo: Veja o que vem:
CdContrato CdObra Soma PCC Soma VCCA 192 206 286.253 835.446.643.200.000.000 192 NULL 286.253 835.446.643.200.000.000 248 312 18.404 4.505.623.069.300.000.000 248 313 0.3022 4.505.623.069.300.000.000 248 314 0.6761 4.505.623.069.300.000.000 248 NULL 28.187 13.516.869.207.900.000.000 NULL NULL 314.440 14.352.315.851.100.000.000 Como você mesmo informou deveria vir assim
Soma PCC Soma VCCA 184.149300 4.610.053.899.700.000.000 Adilson
-
Gapimex, bom dia!
Então fiz como você disse. Olha como estão vindos os valores:
PercentualConclusaoContrato ValorContratoComAditivo 314.440 14.352.315.851.100.000.000 Deveria vir assim:
PercentualConclusaoContrato ValorContratoComAditivo 184,15 208.861.660.800.000.000 Desculpe atrapalhar, eu não sabia que era tão complicado assim. Meus conhecimentos são básico.
OBrigado pela força.
Adilson
-
-
Oi, Jose Segue:
CdContrato CdObra CdMedicaoContratoAditivo PercentuaConclusaoContrato ValorContratoComAditivo 192 206 398 14.347 104.430.830.400.000.000 192 206 398 16.459 104.430.830.400.000.000 192 206 398 20.228 104.430.830.400.000.000 192 206 398 19.870 104.430.830.400.000.000 192 206 398 19.240 104.430.830.400.000.000 192 206 398 16.232 104.430.830.400.000.000 192 206 398 15.110 104.430.830.400.000.000 192 206 398 164.767 104.430.830.400.000.000 192 206 398 0.6633 104.430.830.400.000.000 Adilson
-
-