Jump to content
Fabio93

SQL - Obter datas

Recommended Posts

Fabio93

Boas ,

E o seguinte eu quero fazer um consulta SQL em que me mostre todos os registos em que a data e entre a data de hoje e a da proxima semana .

Alguem me sabe dizer com obtenho a data , para usar algo do genero "WHERE data between 'dia de hj' and 'proxima semana'.

E tb a mesma situaçao com o mes.

E possivel fazer issso ??

Alguem me pode ajudar ???

Obrigado .

Share this post


Link to post
Share on other sites
laboss

tenta assim

SELECT nome FROM clientes WHERE dataRegisto BETWEEN '2011-07-08' and '2011-07-17'

se quiseres algo automatico podes usar o NOW com o  DATE_ADD

SELECT nome FROM clientes WHERE dataRegisto BETWEEN NOW() and DATE_ADD(NOW(), INTERVAL 7 DAY);

Agora depende como tiveres o teu campo date formatado :happybday:

Share this post


Link to post
Share on other sites
Fabio93

As datas estao assim D/M/A.

ex : 09/07/2011

Ja agora

SELECT nome FROM clientes WHERE dataRegisto BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY);

o INTERVAL , pode ser usado com mes ???

por exemplo :

SELECT nome FROM clientes WHERE dataRegisto BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 1 MONTH);

???

Share this post


Link to post
Share on other sites
laboss

Sim pode, entao nos campos tens de meter tipo

DATE_FORMAT(NOW(), '%d/%m/%Y')

DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 7 DAY), '%d/%m/%Y')


SELECT nome FROM clientes WHERE dataRegisto BETWEEN DATE_FORMAT(NOW(), '%d/%m/%Y') AND DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 7 DAY), '%d/%m/%Y');

Deve de funcionar eu nao tenho como testar :happybday:

Share this post


Link to post
Share on other sites
KTachyon

Pah, se as datas foram inseridas na base de dados como tipo date, não precisas de formatar as datas. Elas já são comparáveis.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
brunoais

Elas já são comparáveis.

Só para acrescentar: O MySQL, por exemplo, grava todas as datas em inteiros. Isso torna a comparação extremamente rápida e a conversão e calculo fáceis.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
laboss

mas se as datas estao neste formato 09/07/2011 nao sao o formato do MySQL que e yyyy-mm-dd

Share this post


Link to post
Share on other sites
KTachyon

A data que obténs com NOW() ou com DATE_ADD() está nesse formato? Lê lá aquilo que eu e o brunoais dissemos e pensa lá um bocadinho... :happybday:


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
laboss

nao isso retorna um timespan sao inteiros mas como comparas now's com datas onde os campos sao "strings" ou seja datas formatadas por ele?

Share this post


Link to post
Share on other sites
brunoais

nao isso retorna um timespan sao inteiros mas como comparas now's com datas onde os campos sao "strings" ou seja datas formatadas por ele?

Não percebi


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
laboss

O Fabio93 tem o campo date neste formato 09/07/2011 ou seja DD-MM-YYYY, isto não é o formato DATE do MySQL por norma o formato do campo date do MYSQL é YYYY-MM-DD ou seja ele não consegue fazer consultas filtradas nesse campo através do WHERE usando o NOW sem antes converter pois o MySQL assume aquilo como um string.

SELECT registo FROM clientes WHERE date < NOW()

(Não funciona porque o campo date é varchar e não date/timespan)

Se usar o campo Date com o formato normal ou mesmo um campo TimeStamp ai sim pode filtrar sem recorrer ao DATE_Format.... Ou tou errado? Fiz um teste e confirmou aquilo que disse :| (MySQL 5)

Share this post


Link to post
Share on other sites
Fabio93

SELECT nome FROM clientes WHERE dataRegisto BETWEEN DATE_FORMAT(NOW(), '%d/%m/%Y') AND DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 1 MONTH), '%d/%m/%Y');

laboss , obrigado , o procurar entre hj e a proxima semana funciona , e depois quis fazer o mesmo para o proximo mes e pus assim , mas n da .

Podes dizer-me qual o erro sff ????

Share this post


Link to post
Share on other sites
KTachyon

nao isso retorna um timespan sao inteiros mas como comparas now's com datas onde os campos sao "strings" ou seja datas formatadas por ele?

Se os campos não são dates à partida já está a fazer mal.

O formato que a data tem nos campos para inserção numa base de dados, ou numa pesquisa concreta por uma data é uma coisa. Agora, quando estás a pedir unicamente que a base de dados vá buscar o dia de hoje e o dia daqui a 7 dias, isso é tudo devolvido num formato agnóstico (timestamps) que é comparável, logo não precisas de formatar. Logo é irrelevante o formato que lhes dás na pesquisa, apenas estás a adicionar operações inúteis à query.


“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”

-- Tony Hoare

Share this post


Link to post
Share on other sites
brunoais

Fabio93, mostra aí o código que usaste para criara as tabelas sff. Parece-me q há aqui algo de errado e preciso de ser esclarecido.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
Fabio93

epa nao tenho esse codigo , porque fiz no phpmyadmin

SELECT nome FROM clientes WHERE dataRegisto BETWEEN DATE_FORMAT(NOW(), '%d/%m/%Y') AND DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 1 MONTH), '%d/%m/%Y');

laboss , obrigado , o procurar entre hj e a proxima semana funciona , e depois quis fazer o mesmo para o proximo mes e pus assim , mas n da .

Podes dizer-me qual o erro sff ????

Podes ajudar-me aqui Bruno sff , e Uregente.

Obrigado.

Share this post


Link to post
Share on other sites
brunoais

epa nao tenho esse codigo , porque fiz no phpmyadmin

o phpmyadmin tem um export (vê nos tabs em cima). No export ele inclui o SQL para criar a tabela.


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
Fabio93

epa a data e inserida pelo utilizador e varchar de 10.

E esta organizada assim dd/mm/aaaa.

Share this post


Link to post
Share on other sites
Smoon

eu acho que a origem do problema é que as datas como tu tens estão num formato que dificulta as comparações: dd/mm/yyyy.

Como já disseram o formato normal é yyyy-mm-dd.

A solução que o laboss deu é engenhosa, mas tem um problema... eu acho que essa BETWEEN está a comparar a data guardada na base de dados em string com outras datas em string, e o problema é que por ex. a string "11/07/2011" comparado com "11/08/2011" dá o resultado certo: a 1ª é anterior alfabeticamente e é mais antiga. Mas, "11/07/2011" comparado com "01/08/2011" uma comparação por strings para saber qual a menor (i.e. ordem alfabética) devolvia a 2ª, o que está errado se o objectivo for obter a mais antiga cronologicamente. Por isso é que a solução do laboss funciona bem pra comparar intervalos dentro do mesmo mês, mas não quando pretendes datas em meses diferentes...

[...] quando estás a pedir unicamente que a base de dados vá buscar o dia de hoje e o dia daqui a 7 dias, isso é tudo devolvido num formato agnóstico (timestamps) que é comparável, logo não precisas de formatar. [...]

Mas não é só isso que se quer. É que ele não quer saber só a data do dia de hoje e a data daqui a 7 dias, ele quer saber a comparação da data do dia de hoje (e do dia daqui a 7 dias) com o evento registado na BD no formato mau que traz chatices: dd/mm/yyyy.

Portanto, tens duas soluções:

- ou mudas o modo como estás a guardar a informação na base de dados e passas a usar DATE ou strings no formato yyyy-mm-dd (em vez do formato dd/mm/yyyy antigo, que dificulta as comparações).

- ou fazes algo parecido ao que o laboss sugeriu, mas tens que corrigir aquele problema: 1º tens que comparar de acordo com o ano, depois com o mês, e por fim o dia... portanto tens que inverter a ordem da tua string previamente guardada como dd/mm/yyyy para yyyy/mm/dd... (ou comparar os anos, meses e dias em separado, o que também é chato).

Daqui a pouco, posso indicar algum código se tiver tempo pra testar, mas a ideia é essa.

Share this post


Link to post
Share on other sites
brunoais

Nada melhor que um DATE, DATETIME ou TIMESTAMP para fazer cálculos e tratar de datas...


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
Smoon

select substring('11/07/2011', 1, 2);
select substring('11/07/2011', 4, 2);
select substring('11/07/2011', 7, 4);

cada linha devolve-te, respectivamente, o dia, o mês ou o ano da string '11/07/2011'.

select DATE('2011-07-11');

converte-te uma string no formato yyyy-mm-dd para data;

DATE(concat(substring('11/07/2011', 7, 4), '-', substring('11/07/2011', 4, 2), '-', substring('11/07/2011', 1, 2)))

portanto, com isto em mysql converto a string '11/07/2011' para uma variável DATE do tipo yyyy-mm-dd (ex: 2011-07-11).

[De acordo com o que procurei na net deveria haver uma alternativa em SQL server mais curta e directa:

SELECT convert(datetime, '11/07/2011', 103);

(http://msdn.microsoft.com/en-us/library/ms187928.aspx)

mas não consigo usá-la com mysql.]

Então, juntando o que indiquei antes, em vez de comparares strings no formato dd/mm/yyyy, podes converter a tua string para DATE e comparar com as outras DATEs assim, em MySQL:

SELECT nome FROM clientes
WHERE DATE(concat(substring(data_registo, 7, 4), '-', substring(data_registo, 4, 2), '-', substring(data_registo, 1, 2))) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY);

testei com uma pequena tabela que criei hoje e funciona bem, quer com 7 DAY, quer com 1MONTH, etc.

Repara que em vez de usar NOW(), uso CURDATE(); o motivo é que, pelo que percebi, só interessa comparar os dias do registo, não é? Então usamos variáveis tipo DATA sem incluir as horas, minutos e segundos, pois não interessam para a comparação... (date and time functions: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html).

(*edit* para clarificar)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.