Comparando mês e ano entre duas datas no SQL Server

SQL Server

22/09/2015

Olá pessoal,
Tem duas datas(mm/yyyy), tenho que compar pelo mês e ano, fiz a seguinte condição, mas quando o mês tem zero na frente e comparo com um mês que tenha dois digitos, essa minha condição não atende.

Concatenei mes e ano, e converti para inteiro, assim comparo as duas datas como inteiros.


Exemplo:
Quando tenho as datas

@DATA_PAGTO DATETIME = CONVERT(SMALLDATETIME, 20141229, 112),
@DATA_ATUAL_SIMULACAO DATETIME = CONVERT(SMALLDATETIME, 20150105, 112)

WHILE CAST(LTRIM(RTRIM(CONVERT(VARCHAR(2),DATEPART(MM,@DATA_CORRENTE)))) + CONVERT(CHAR(4),DATEPART(YEAR,@DATA_CORRENTE)) AS INT) 
<= 
CAST(LTRIM(RTRIM(CONVERT(CHAR(2),DATEPART(MONTH,@DATA_ATUAL_SIMULACAO)))) + CONVERT(CHAR(4),DATEPART(YEAR,@DATA_ATUAL_SIMULACAO)) AS INT) 


Alguém conhece uma melhor forma de fazer essa comparação?
Max

Max

Curtidas 0

Respostas

Alex Lekao

Alex Lekao

22/09/2015

Acompanhando.
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

bom dia a todos.
acho que o codigo abaixo ira atender o que procura. forçando que o mesmo venha 2 digitos para meses que so tem um.
no meu preciso atualizar produtos apartir de item e subitem etc.
espero que ajude

caminho = c:\etc+ right('00' + cast(coditem as varchar(6)),2) + '_' +
(CASE WHEN LEN(subitem)=3 THEN CAST(subitem AS VARCHAR(3)) ELSE right('00' + cast(subitem as varchar(2)),2)
GOSTEI 0
Hector Figueroa

Hector Figueroa

22/09/2015

Boas Max, tranquilo? faça o teste com a SQL:

select *
from tabela
where month(data) = month('20140529')
 and year(data) = year('20140529')
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

bom dia a todos.
acho que o codigo abaixo ira atender o que procura. forçando que o mesmo venha 2 digitos para meses que so tem um.
no meu preciso atualizar produtos apartir de item e subitem etc.
espero que ajude

caminho = c:\etc+ right('00' + cast(coditem as varchar(6)),2) + '_' +
(CASE WHEN LEN(subitem)=3 THEN CAST(subitem AS VARCHAR(3)) ELSE right('00' + cast(subitem as varchar(2)),2)



algo tipo isso


SELECT
(right('00' + cast((SELECT DATEPART(MONTH,GETDATE())) as varchar(2)),2) ) AS TESTE
GOSTEI 0
Max

Max

22/09/2015

Então, estou fazendo uma comparação, onde converto o mê e ano cocatenados para int, é nessa conversão que o 0(zero) se perde.
A forma que eu encontrei para para comparar a data(mes/ano). Preciso comparar essa duas data(mes/ano), de uma data que eu recebo até a data atual.


@DATA_PAGTO DATETIME = CONVERT(SMALLDATETIME, 20141229, 112),
@DATA_ATUAL_SIMULACAO DATETIME = CONVERT(SMALLDATETIME, 20150105, 112)

WHILE CAST(LTRIM(RTRIM(CONVERT(VARCHAR(2),DATEPART(MM,@DATA_CORRENTE)))) + CONVERT(CHAR(4),DATEPART(YEAR,@DATA_CORRENTE)) AS INT) 
<= 
CAST(LTRIM(RTRIM(CONVERT(CHAR(2),DATEPART(MONTH,@DATA_ATUAL_SIMULACAO)))) + CONVERT(CHAR(4),DATEPART(YEAR,@DATA_ATUAL_SIMULACAO)) AS INT) 
BEGIN
         SET @DATA_CORRENTE = DATEADD(MONTH,1, @DATA_CORRENTE)	
END



Comparando as datas com as soluções acima, eu não teria como fazer a condição de data_01 <= data_02. Não sei se estou errado, ou se consegui me fazer entender.
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

boa tarde.
do jeito que coloquei acima sua data vai ficar 092015 pensei que era isso.

amigo uma pratica que eu utilizo é particionar a data pois a mesma é o campo ideal para comparações .
nas tabelas que eu crido eu costumo criar 3 campos para data.
ex. data '22/09/2015' fazer uma comparação com um campo desses é uma "Pipoca" para o desempenho de um Banco.
por esse motivo eu os separo BintAno é um campo do tipo bigint que recebera a data 2015 TintMes é um campo tinyint que recebe 9 ou 09 e TintDia que recebe 22

com isso na hora das comparações ficam muito mais rapidas devido aos seus tipos . se possivel pense nisso para uma possivel aplicação no seu dia a dia.
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

boa tarde.
do jeito que coloquei acima sua data vai ficar 092015 pensei que era isso.

amigo uma pratica que eu utilizo é particionar a data pois a mesma é o campo ideal para comparações .
nas tabelas que eu crido eu costumo criar 3 campos para data.
ex. data '22/09/2015' fazer uma comparação com um campo desses é uma "Pipoca" para o desempenho de um Banco.
por esse motivo eu os separo BintAno é um campo do tipo bigint que recebera a data 2015 TintMes é um campo tinyint que recebe 9 ou 09 e TintDia que recebe 22

com isso na hora das comparações ficam muito mais rapidas devido aos seus tipos . se possivel pense nisso para uma possivel aplicação no seu dia a dia.



ou uma coisa que eu faria nesse caso seria com substring

como abaixo pelas datas que vc colocou acima. mais nao sei se te atende.

SELECT SUBSTRING('20141229',1,6) AS DtInicio
SELECT SUBSTRING('20150105',1,6) AS DtFim
GOSTEI 0
Max

Max

22/09/2015

Isaac,
Primeiro, achei bem bacana a sua dica de quebrar a data, valeul pela dica. Só que o modelo já está pronto e não dá pra alterar agora.

Realmente preciso desse valor "092015", que seria mes+ano, por isso fiz um cast para int, para comparar.
Só que quando eu faço o cast o resultado é 92015.

Por exemplo tem duas datas '01/11/2014' e '05/01/2015'


Eu faço uma condição verificando se a data '112014' <= 12015, como a conversão tirou o "0" a condição é falsa.
GOSTEI 0
Max

Max

22/09/2015

Escrevendo o ultimo post, verifiquei que mesmo colocando o "0", a condição continuaria falsa. Minha logica está furada.
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

da pra fazer com o substing mesmo

SELECT SUBSTRING('20141229',1,6) AS DtInicio resultado 201412
SELECT SUBSTRING('20150105',1,6) AS DtFim resultado 201501

se nao der certo depois do almoço monto algo em cima desse cara aqui
"Por exemplo tem duas datas '01/11/2014' e '05/01/2015'"
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

Segue.
SELECT SUBSTRING('01/11/2014' ,4,2)+SUBSTRING('01/11/2014',7,4) DtInicio --RESULTADO 112014
SELECT SUBSTRING('05/01/2015' ,4,2)+SUBSTRING('05/01/2015',7,4) DtFinal --RESULTADO 012015
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

sim mais deve comprarar primeiro o ano depois o mes .

e com isso mmyyyy vc esta comparando 112014 que é maior que 012015. porem menos mau so inverter ..
GOSTEI 0
Max

Max

22/09/2015

Isaac,
Era isso mesmo, ano e depois o mês.
Acredito que deva ter uma forma melhor de comparar ano/mês no sql.

Ficou assim.


WHILE 
         CAST(SUBSTRING(CONVERT(NVARCHAR(10),@DATA_CORRENTE,103),7,4) + SUBSTRING(CONVERT(NVARCHAR(10),@DATA_CORRENTE,103) ,4,2) AS INT) 
         <=      
        CAST(SUBSTRING(CONVERT(NVARCHAR(10),GETDATE(),103),7,4) + SUBSTRING(CONVERT(NVARCHAR(10),GETDATE(),103) ,4,2) AS INT)
BEGIN
      PRINT 'TESTE'
      SET @DATA_CORRENTE = DATEADD(MONTH,1, @DATA_CORRENTE)	
END 



Valeu....
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

Por nada.
se precisar é do postar tentarei ajudar na medida do possivel.

abraços.
GOSTEI 0
Isaac Jose

Isaac Jose

22/09/2015

Isaac,
Era isso mesmo, ano e depois o mês.
Acredito que deva ter uma forma melhor de comparar ano/mês no sql.

Ficou assim.


WHILE 
         CAST(SUBSTRING(CONVERT(NVARCHAR(10),@DATA_CORRENTE,103),7,4) + SUBSTRING(CONVERT(NVARCHAR(10),@DATA_CORRENTE,103) ,4,2) AS INT) 
         <=      
        CAST(SUBSTRING(CONVERT(NVARCHAR(10),GETDATE(),103),7,4) + SUBSTRING(CONVERT(NVARCHAR(10),GETDATE(),103) ,4,2) AS INT)
BEGIN
      PRINT 'TESTE'
      SET @DATA_CORRENTE = DATEADD(MONTH,1, @DATA_CORRENTE)	
END 



Valeu....


uma coisa o nvarchar tem um tamanho de mais ou menos 65.500 posições vc o limitou e esta correto porem o tamanho do banco aumenta. procure utilizar sempre o menor possivel.
no caso o varchar é 255 a principio não tem problemas mais ja muitas aplicações de clientes que pararam de rodar pela utilização desses campos que aparecem principalmente ao criar tabelas pelo Wizard.... mais é só um tok...
abraços.
GOSTEI 0
Max

Max

22/09/2015

Opa,
Mais uma dica, sempre bem vinda.

Valeu Isaac!!!!
GOSTEI 0
POSTAR