[MySQL] Wie hiervoor een query weet is een koning

Pagina: 1
Acties:
  • 214 views sinds 30-01-2008
  • Reageer

  • finnyhut
  • Registratie: Augustus 2000
  • Laatst online: 27-05 06:31
Ik heb een tabel 'leden' met in elke rij een date-veld geboortedatum (YYYY/MM/DD).
De grote vraag is hoe kan ik mbv een MySQL query de mensen selecteren die het eerst jarig zijn na de huidige datum?
Er moet ook rekening worden gehouden met meerdere mensen die op die dag jarig kunnen zijn en de mensen die op de huidige dag zelf jarig zijn tellen niet mee.

Ik zit hier al dagen over na te denken maar ik kan geen query bedenken. Ik kom niet verder dan iedereen selecteren en het met PHP te berekenen, maar dat is nogal inefficient....

  • Onno
  • Registratie: Juni 1999
  • Niet online
Hmm... in Oracle zou ik zoiets doen:

select to_char(geboortedatum,'DD month') as verjaardag, mod(to_number(to_char(geboortedatum,'DDD'))-to_number(to_char(sysdate,'DDD'))+365,365) as aantaldagentotverjaardag from blaat order by aantaldagentotverjaardag;

Het werkt niet perfect (er is nog geen rekening gehouden met schrikkeljaren, daar wordt de query nog ietsje langer van) maar wel enigszins.

Ik kan je geen MySQL query geven, heb geen flauw idee wat voor functies MySQL heeft enzo. :)

(oh ja... DDD zorgt voor de dag van het jaar, da's wel nuttig om te weten, wil je iets van deze query snappen)

Verwijderd

euh...
om eerst de eerstvolgende datum te krijgen:

select datum from bla where datum > 'vandaag' order by datum asc limit 1;

dan alle personen met die datum:

select * from bla where datum = 'datum-uit-de-vorigequery'

  • Onno
  • Registratie: Juni 1999
  • Niet online
Dat gaat niet echt lekker werken zo tegen het einde van het jaar he? :)

Verwijderd

Op zondag 04 februari 2001 01:04 schreef Onno het volgende:
Dat gaat niet echt lekker werken zo tegen het einde van het jaar he? :)
waarom niet?
ik heb het getest op een db-tje met data en ook op een dag als 31 dec. doet hij het gewoon.... ;)

  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Ik weet niet of die functie in mysql zit maar je kan misschien testen op datediff

  • InNuedo
  • Registratie: Maart 2000
  • Laatst online: 22-04 15:02
Erhm

dit werkt bij mij al tijden perfect:

$date = date("Y-m-d");
$result = mysql_db_query("DBNAAM","SELECT * FROM TABLENAAM WHERE datum > '$date'");

en dan heb je iedereen die na de huidige datum jarig is.

  • finnyhut
  • Registratie: Augustus 2000
  • Laatst online: 27-05 06:31
$date = date("Y-m-d");
$result = mysql_db_query("DBNAAM","SELECT * FROM TABLENAAM WHERE datum > '$date'");

en dan heb je iedereen die na de huidige datum jarig is.
Lijkt me niet, date("Y-m-d") geeft bv. 2001-02-04 en een geboortedatum is bv. 1970-05-12. Dat gaat dus niet werken. Geboortedatum is niet groter dan de huidige datum.

En al zou het werken dan heb je nog niet alleen degene(n) geselecteerd die als eerste jarig zijn na de huidige datum.

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Select personen, (to_days(now()) - to_days(geboortedatum)) /365 as leeftijd from leden order by leeftijd

Heb hem nog niet geprobeerd maar hij zou moeten werken

HTH

edit:

Haakje vergeten

Programmer - an organism that turns coffee into software.


  • Onno
  • Registratie: Juni 1999
  • Niet online
waarom niet?
Omdat de geboortedatum bekend is, niet de eerstkomende verjaardag.
Select personen, (to_days(now()) - to_days(geboortedatum)) /365 as leeftijd from leden order by leeftijd
Heb hem nog niet geprobeerd maar hij zou moeten werken
Lijkt mij niet. Wat bereken je hier? Het aantal jaren dat iemand oud is. Is iemand van 83 per se eerder jarig dan iemand van 12? Nee toch?

  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Je zou moeten proberen om het jaar uit te sluiten in de query. Volgens mij is er geen manier om dit te doen uin MySQL (immers 31-7-1981 kan NOOIT na 3-01-2001 oid liggen!)

Ik denk niet dat dit kan -> oplossing alle leden selecteren, lijkt me

If you are not wiping out you are nog pushing enough...


  • Onno
  • Registratie: Juni 1999
  • Niet online
Kun je in MySQL niet de dag v/h jaar van een datum selecten??? Vaag.

  • finnyhut
  • Registratie: Augustus 2000
  • Laatst online: 27-05 06:31
Kun je in MySQL niet de dag v/h jaar van een datum selecten??? Vaag.
Ja dat kan wel, mbv DAYOFYEAR(datum).

Op dit moment doe ik het zo:

SELECT (DAYOFYEAR(geboortedatum) - DAYOFYEAR(NOW())) as dagentegaan FROM personen ORDER BY DAYOFYEAR(geboortedatum) DESC

Dan krijg je als resultaat van elke persoon hoeveel dagen er nog te gaan zijn totdat hij/zij jarig is. Dit getal is dus negatief als hij/zij al jarig is geweest dit jaar.

Van deze verzameling getallen zoek ik het positieve getal op dat het dichtste bij nul ligt. En selecteer de gegevens van de persoon (of personen) die daarbij horen. Mocht iedereen dit jaar al jarig geweest zijn dat neem ik het meest negatieve getal, aangezien die het vroegst in het jaar valt.

Ik begin te twijfelen of het wel mogelijk is om alléén de persoon of personen te selecteren die het eerste jarig is/zijn na de huidige datum. Btw dit is natuurlijk altijd op één datum, maar er zouden meerdere personen op die datum jarig kunnen zijn....

  • Onno
  • Registratie: Juni 1999
  • Niet online
Dit getal is dus negatief als hij/zij al jarig is geweest dit jaar.
Maar dat is te fixen door er een modulo op los te laten, zoals ik deed... Ik geloof dat dat % in MySQL is?

SELECT ((DAYOFYEAR(geboortedatum) - DAYOFYEAR(NOW())+365) % 365) as dagentegaan FROM personen ORDER BY dagentegaan

Verwijderd

[Offtopic]
is SELECT * FROM iets LIMIT 1; sneller dan SELECT * FROM iets; ????
[/Offtopic]

  • Onno
  • Registratie: Juni 1999
  • Niet online
Als er geen ORDER BY of GROUP BY in voor komt kan dat veel sneller zijn. Met maakt het vrij weinig uit denk ik.

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Op zondag 04 februari 2001 11:30 schreef Onno het volgende:

[..]

Omdat de geboortedatum bekend is, niet de eerstkomende verjaardag.
[..]

Lijkt mij niet. Wat bereken je hier? Het aantal jaren dat iemand oud is. Is iemand van 83 per se eerder jarig dan iemand van 12? Nee toch?
Misschien moet ik beter lezen... |:( of meer koffie drinken

Probeer dit

select if(period_diff(Dayofyear(datetime),dayofyear(now()))<0,365 + period_diff(dayofyear(datetime),dayofyear(now())) ,period_diff(dayofyear(datetime),dayofyear(now()))) as M,id from leden order by M

Programmer - an organism that turns coffee into software.


  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Op zondag 04 februari 2001 13:02 schreef ]DrPain[ het volgende:
[Offtopic]
is SELECT * FROM iets LIMIT 1; sneller dan SELECT * FROM iets; ????
[/Offtopic]
http://www.mysql.com/doc/L/I/LIMIT_optimization.html
In some cases MySQL will handle the query differently when you are using LIMIT # and not using HAVING:

If you are selecting only a few rows with LIMIT, MySQL will use indexes in some cases when it normally would prefer to do a full table scan.
If you use LIMIT # with ORDER BY, MySQL will end the sorting as soon as it has found the first # lines instead of sorting the whole table.
When combining LIMIT # with DISTINCT, MySQL will stop as soon as it finds # unique rows.
In some cases a GROUP BY can be resolved by reading the key in order (or do a sort on the key) and then calculate summaries until the key value changes. In this case LIMIT # will not calculate any unnecessary GROUP BY's.
As soon as MySQL has sent the first # rows to the client, it will abort the query.
LIMIT 0 will always quickly return an empty set. This is useful to check the query and to get the column types of the result columns.
The size of temporary tables uses the LIMIT # to calculate how much space is needed to resolve the query.
Met limit is een MySQL aanzienlijk sneller... of je tabel moet natuurlijk erg klein zijn dan maakt het niet uit(lees je merkt het verschil niet)...

Programmer - an organism that turns coffee into software.


Verwijderd

finnyhut: Ik heb een tabel 'leden' met in elke rij een date-veld geboortedatum (YYYY/MM/DD).
De grote vraag is hoe kan ik mbv een MySQL query de mensen selecteren die het eerst jarig zijn na de huidige datum?


Oke, het is niet fraai maar het werkt:
code:
1
2
3
4
5
6
 SELECT naam,
    SIGN(DAYOFYEAR(geboortedatum)-DAYOFYEAR(NOW())) AS y,
    DAYOFYEAR(geboortedatum)-DAYOFYEAR(NOW()) AS x
FROM leden
WHERE x
ORDER BY y DESC, x ASC

  • FragDaddy
  • Registratie: Mei 2000
  • Laatst online: 27-05 09:41
1 ding.. ORDER BY date

en de rest zoek je zelf maar ff uit een SQL handleiding. :)

Have a wheelie good weekend!


  • a casema user
  • Registratie: Januari 2000
  • Laatst online: 27-05 23:02
Ik wil niet zeuren hoor, maar ik heb hetzelfde probleem pas geleden ook al gepost.

gathering.tweakers.net/showtopic/116877

Helaas ben ik daarmee niet veel wijzer geworden, maar er staat wel een oplossing voorje probleem. *D

Taaaa taa taa taaaa taa taa ta taaataaaaa.


  • finnyhut
  • Registratie: Augustus 2000
  • Laatst online: 27-05 06:31
Op zondag 04 februari 2001 13:50 schreef FragDaddy het volgende:
1 ding.. ORDER BY date

en de rest zoek je zelf maar ff uit een SQL handleiding. :)
Lees eerst de vraag eens aandachtig voordat je met dit soort reacties komt. Dit heeft er niets mee te maken.
Op zondag 04 februari 2001 14:41 schreef a casema user het volgende:
Ik wil niet zeuren hoor, maar ik heb hetzelfde probleem pas geleden ook al gepost.
Dit is een heel ander probleem, jij wilde iedereen selecteren die binnen 7 dagen jarig is, ik wil alleen de persoon selecteren die als éérste jarig is, dat kan over een dag zijn, over een week of over een maand.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15:26

Janoz

Moderator Devschuur®

!litemod

code:
1
2
3
4
SELECT andere dingen, 
       MOD((DAYOFYEAR(geboortedatum)+356)-DAYOFYEAR(CURDATE()),356) as DaystoBday 
       FROM tabel 
       ORDER BY DaystoBday;

Deze houdt alleen nog geen rekening met schrikkeljaar.. Moet je alleen nog ff het totaal antal dagen van het jaar ophalen (met iets als DAYOFYEAR(31-12-CURYEAR) ofzoachtigiets)

[edit]ff een + totaal aantal dagen toegevoegd omdat de mod bv -5 -> -5 doet ipv -5 -> 360

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • finnyhut
  • Registratie: Augustus 2000
  • Laatst online: 27-05 06:31
Nou het lijkt erop dat Janoz de koning is in dit geval :) Ik heb de query even afgemaakt:
code:
1
2
3
4
5
6
7
8
SELECT MIN( MOD( (DAYOFYEAR(gebdatum)+DAYOFYEAR(CONCAT(YEAR(CURDATE()),'-12-31')))
                           - DAYOFYEAR(CURDATE()),
                           DAYOFYEAR(CONCAT(YEAR(CURDATE()),'-12-31'))
                  )     ) as eerstvolgendejarige

FROM tabel

WHERE DAYOFYEAR(gebdatum) != DAYOFYEAR(CURDATE())

In de select rekent ie het aantal dagen uit dat nog te gaan is voor de volgende verjaardag. Als je pas volgend jaar weer jarig bent komt er dus een getal groter dan 365 uit. Daarvan selecteer je het minimum, want die is als eerste jarig.

In de where clause worden tenslotte degenen uitgesloten die op de huidige dag jarig zijn. Aangezien die dan altijd de MIN() zouden 'winnen', omdat ze nog 0 dagen te gaan hebben. En het ging mij erom degene te selecteren die als eerste jarig is.

Nou het is dus gelukt, bedankt!!

  • Onno
  • Registratie: Juni 1999
  • Niet online
Nou het lijkt erop dat Janoz de koning is in dit geval :)
Hmm, een zelfde query gaf ik meer dan een dag eerder al hoor :P ;)

  • finnyhut
  • Registratie: Augustus 2000
  • Laatst online: 27-05 06:31
Zo'n vermoeden had ik al Onno, maar ik begreep die Oracle query niet echt met al die D'tjes :? Dus vandaar....

  • Onno
  • Registratie: Juni 1999
  • Niet online
Op zondag 04 februari 2001 12:53 schreef Onno het volgende:

SELECT ((DAYOFYEAR(geboortedatum) - DAYOFYEAR(NOW())+365) % 365) as dagentegaan FROM personen ORDER BY dagentegaan
Die dus :P

Verwijderd

Op zondag 04 februari 2001 13:19 schreef Arien het volgende:
Oke, het is niet fraai maar het werkt:
code:
1
2
3
4
5
6
 SELECT naam,
    SIGN(DAYOFYEAR(geboortedatum)-DAYOFYEAR(NOW())) AS y,
    DAYOFYEAR(geboortedatum)-DAYOFYEAR(NOW()) AS x
FROM leden
WHERE x
ORDER BY y DESC, x ASC
En wat werkt er volgens jou hier niet aan? (Behalve schrikkeljaren waar de andere oplossing ook geeen raad mee weet.)

En als je er een wilt hebben dan kan je dat met LIMIT doen.

Verwijderd

sjako is weer thuis en probeert het ook eens :

Zet de maand/dag om naar een getal van vier cijfers :
code:
1
2
3
4
5
6
select naam
,      verjaardag
,      to_char(verjaardag,'MMDD') dag
from   verjaardagen
where  to_char(verjaardag,'MMDD') > to_char(sysdate,'MMDD')
order by dag asc

De Mysql date functions ken ik zo niet uit mijn hoofd. Moet je ff opzoeken
:)

edit:


Heb zelf ff snel gezocht (kan het niet laten) :
[code]select naam
, verjaardag
, date_format(verjaardag,'%m%d') as dag
from verjaardagen
where date_format(verjaardag,'%m%d') > date_format(sysdate(),'%m%d'))
order by dag asc[/code]


Voor het schrikkeljaar probleem ben je nu klaar.
Je moet het wel ff aanpassen voor mensen die 'volgend jaar' jarig zijn.

Verwijderd

Had ff wat tijd en heb het maar ff afgemaakt :
code:
1
2
3
4
5
6
7
select naam
,      verjaardag
,      date_format(verjaardag,'%m%d') as dag
,      sign(date_format(verjaardag,'%m%d') - date_format(sysdate(),'%m%d')) as test
from   verjaardagen
where  date_format(verjaardag,'%m%d') <> date_format(sysdate(),'%m%d')
order by test desc,dag asc

edit:

knippenenplakken werkt beter dan ff snel overkloppen :)
Pagina: 1