Usuário com melhor resposta
Ajuda na montagem de SQL com datas

Pergunta
-
Olá!
Preciso converter o trecho abaixo, escrito em VB6 para acesso ao PostgreSQL, para o padrão do SQL Server 2008...
vSql = "Select Sum(VolRecA20) as VolRec, Sum(VolFatA20) as VolFat," vSql = vSql & " tbProcessos.CodProd From tbDistribuicoes inner join tbProcessos" vSql = vSql & " on tbDistribuicoes.CodProcesso = tbProcessos.NrProcesso" ' CORRIGIR ---------------- vSql = vSql & " Where (to_char(dtDistrib,'MMYYYY')='" & Format(nSql, "mmyyyy") ' ------------------------- vSql = vSql & "' and tpProcesso='E') Group By tbProcessos.CodProd" vSql = vSql & " Order By tbProcessos.CodProd;"
E também este trecho:
' Procura funcionários aniversariantes no dia ' CORRIGIR ---------------------- vSql = "Select id, NomeFunc, dtNascto from tbFuncs" vSql = vSql & " where (to_char(dtNascto,'dd/mm') between '" vSql = vSql & Format(vDom, "dd/mm") & "' and '" & Format(vDom + 6, "dd/mm") vSql = vSql & "' and dtDemissao='') order by NomeFunc;" ' -------------------------------
Me aventurando no VB 2005...- Movido AndreAlvesLima sexta-feira, 17 de julho de 2009 12:07 (De:VB.NET e Visual Basic)
- Movido Gustavo Maia Aguiar terça-feira, 21 de julho de 2009 01:34 (De:SQL Server - Desenvolvimento Geral)
Respostas
-
Boa Tarde,
Segue uma alternativa. Vale a pena lembrar que esse tipo de construção (e a TO_CHAR do Postgree) são péssimas do ponto de vista de desempenho.declare @pessoas table (nome varchar(20), datanasc smalldatetime) insert into @pessoas values ('Fulano 1','19500720') insert into @pessoas values ('Fulano 2','19670719') insert into @pessoas values ('Fulano 3','19800730') insert into @pessoas values ('Fulano 4','19830729') insert into @pessoas values ('Fulano 5','19690728') insert into @pessoas values ('Fulano 6','19790726') insert into @pessoas values ('Fulano 7','19880724') insert into @pessoas values ('Fulano 8','19880716') insert into @pessoas values ('Fulano 9','19880718') -- Os aniversariantes de hoje select * from @pessoas where month(datanasc) = month(getdate()) and day(datanasc) = day(getdate()) -- Retorna os aniversariantes da semana (do último domingo até o próximo) -- Considera que a semana se inicia no domingo select * from @pessoas where month(datanasc) = month(getdate()) and day(datanasc) between day(getdate()) - (7 - @@datefirst + 1) and day(getdate()) + (@@datefirst - 1)
[ ]s,
Gustavo Maia Aguiar
http://gustavomaiaaguiar.spaces.live.comMitos do SQL Server – A ordem das tabelas influencia no desempenho de uma instrução SELECT ?
http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!643.entry
Classifique as respostas. O seu feedback é imprescindível- Sugerido como Resposta Gustavo Maia Aguiar segunda-feira, 20 de julho de 2009 18:06
- Marcado como Resposta Fernanda Simões terça-feira, 4 de agosto de 2009 19:16
Todas as Respostas
-
Sandro,
Olhe o link abaixo se pode te ajudar. Agora acho que a diferença para você converter esse query para o SQL Server está basicamente no to_char e Format que no SQL Server é realizado de outra forma.
http://dicasdecodigo.blogspot.com/2008/02/formatar-data-com-o-microsoft-sql.html
Flwz
Robinson -
Robinson, a questão é exatamente sobre o "to_char"... que alternativa funcionaria nos casos apresentados?
Acontece que postei com pressa, e também porque estou "correndo contra o tempo" nesta mudança de base...
já corrigi os sqls do sistema inteiro, mas ficou faltando o caso do to_char...
Só explicando...
- no primeiro trecho, o "nSql" é uma variável que contém uma data... então preciso do where pegando apenas a parte Mês-Ano para comparação.
- no segundo trecho, o "vDom" também é uma data, e eu preciso selecionar os funcionários aniversariantes de uma semana especificada (vDom a vDom+6).
Quanto ao link que me mandou, vou tentar ler ele com calma depois... me pareceu bem interessante.
Sandro.
Me aventurando no VB 2005... -
-
-
Ola Sandro,
Segue exemplo da query em T-sql
Select Sum(VolRecA20) as VolRec, Sum(VolFatA20) as VolFat, tbProcessos.CodProd From tbDistribuicoes inner join tbProcessos on tbDistribuicoes.CodProcesso = tbProcessos.NrProcesso Where left('0'+cast(month(dtDistrib) as char(2)),2)+cast(year(dtDistrib) as char(4))='" & Format(nSql, "mmyyyy")"' and tpProcesso='E' Group By tbProcessos.CodProd Order By tbProcessos.CodProd;
Att.
Marcelo Fernandes
MCP, MCDBA, MCSA, MCTS. Se útil, classifique!!! -
Ok, Marcelo, vou testar...
Agora, continuo com dificuldade no segundo trecho... tentei utilizar o Day() e o Month(), mas o resultado não me convenceu...
O propósito do segundo trecho é o preencher um formulário com os aniversariantes da semana (ou seja, de vDom a vDom+6).
Claro que fazer um Where comparando Day(data) e Month(data) resolve, porém gera a necessidade de se fazer 7 selects, um para cada dia da semana.
E esta é uma solução que não me agrada...
Eu prefiro utilizar apenas 1 Select, que me retorne todos os aniversariantes da semana e então, através de um Select Case do VB eu posiciono cada um onde eu quero.
Por esta razão, usar o Day e o Month não resolve, pois fazer o between esbarra em semanas onde termina um mês e começa outro, bem como mudança de ano... em que o dia 29 nunca será menor que o dia 1 quando vistos isoladamente.
Vejam: where ( (Day(Nascto) between Day(Now) and Day(Now+7)) and (Month(Nascto) between Month(Now) and Month(Now+7) )
Bem... aí está.
Me aventurando no VB 2005... -
Sandro,
Tem uma maneira mais simples para fazer o q vc quer, descobrindo o numero da semana, segue exemplo
declare @tabela as table (nome varchar(10), dtNasc datetime)
insert into @tabela values('marcelo','20090717')
insert into @tabela values('marcelo2','20090617')
insert into @tabela values('marcelo3','20090721')
select * from @tabela WHERE DATEPART(wk, GETDATE()) = DATEPART(wk, dtNasc)
Att.
Marcelo Fernandes
MCP, MCDBA, MCSA, MCTS. Se útil, classifique!!! -
Sandro,
Você conseguiu solucionar o seu problema?
Caso afirmativo poste a solução para que outras pessoas se beneficiem.Att,
Fernanda
“Caso esta resposta tenha ajudado a solucionar sua dúvida, favor clicar em “Marcar como Resposta” para beneficiar outros membros da comunidade que estejam lendo este thread”. -
-
Desculpem a demora em responder...
Mas vamos lá:
fiz alguns testes e nada resolveu meu problema até agora (o to_char do postgre atendia completamente..rsrsr).
No caso da combinação Day/Month que coloquei acima, de fato quando há a mudança de mês dentro do período que especifico (vDom até vDom+6) a comparação não funciona, pois o dia inicial do período é sempre maior que o dia final do período.
No caso do DatePart sugerido pelo Marcelo, só funciona quando há a coincidência da data de nascimento do funcionário ter caído numa semana igual (em termos de sequência numérica, 10ª semana, 13ª semana...) à semana em que a data do período cai.
O problema todo está no fato de que as datas de nascimento são armazenadas com o ano de nascimento, enquanto que a busca revere-se ao ano informado no vDom.
Para sair deste dilema, precisa haver comparação apenas de dia e mês e, mais ainda, dentro de um período definido.
Infelizmente estou no meio da revisão de um sistema e sem tempo para quebrar a cabeça com este dilema...
Esta foi a razão pela qual estou apelando ao conhecimento dos colegas do fórum... ver se alguém já passou por isso e como superou o caso.
Agora, podem ficar tranquilos, pois quando eu encontrar uma solução, certamente irei publicar aqui!!
Por ora...
Sandro.
Me aventurando no VB 2005... -
Boa Tarde,
Segue uma alternativa. Vale a pena lembrar que esse tipo de construção (e a TO_CHAR do Postgree) são péssimas do ponto de vista de desempenho.declare @pessoas table (nome varchar(20), datanasc smalldatetime) insert into @pessoas values ('Fulano 1','19500720') insert into @pessoas values ('Fulano 2','19670719') insert into @pessoas values ('Fulano 3','19800730') insert into @pessoas values ('Fulano 4','19830729') insert into @pessoas values ('Fulano 5','19690728') insert into @pessoas values ('Fulano 6','19790726') insert into @pessoas values ('Fulano 7','19880724') insert into @pessoas values ('Fulano 8','19880716') insert into @pessoas values ('Fulano 9','19880718') -- Os aniversariantes de hoje select * from @pessoas where month(datanasc) = month(getdate()) and day(datanasc) = day(getdate()) -- Retorna os aniversariantes da semana (do último domingo até o próximo) -- Considera que a semana se inicia no domingo select * from @pessoas where month(datanasc) = month(getdate()) and day(datanasc) between day(getdate()) - (7 - @@datefirst + 1) and day(getdate()) + (@@datefirst - 1)
[ ]s,
Gustavo Maia Aguiar
http://gustavomaiaaguiar.spaces.live.comMitos do SQL Server – A ordem das tabelas influencia no desempenho de uma instrução SELECT ?
http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!643.entry
Classifique as respostas. O seu feedback é imprescindível- Sugerido como Resposta Gustavo Maia Aguiar segunda-feira, 20 de julho de 2009 18:06
- Marcado como Resposta Fernanda Simões terça-feira, 4 de agosto de 2009 19:16