2 weken voor een datum en 2 weken na een datum vinden
In mijn database heb ik geboortedatum staan, datefield,
met deze code
Code (php)
1
2
3
2
3
where ((abs(DATEDIFF(MAKEDATE(YEAR(CURDATE()), DAYOFYEAR(geboortedatum)), CURDATE()))<15)
or (abs(DATEDIFF(MAKEDATE(YEAR(CURDATE())+1, DAYOFYEAR(geboortedatum)), CURDATE()))<15)
or (abs(DATEDIFF(MAKEDATE(YEAR(CURDATE())-1, DAYOFYEAR(geboortedatum)), CURDATE()))<15))
or (abs(DATEDIFF(MAKEDATE(YEAR(CURDATE())+1, DAYOFYEAR(geboortedatum)), CURDATE()))<15)
or (abs(DATEDIFF(MAKEDATE(YEAR(CURDATE())-1, DAYOFYEAR(geboortedatum)), CURDATE()))<15))
Deze code is echter traag omdat ze eigenlijk 3X wordt uitgevoerd. Dit is nodig omdat anders net voor 1-1 en ne na 1-1 het andere jaar niet wordt meegenomen.
Iemand een idee om dit korter/sneller te maken?
Jan
Gewijzigd op 01/09/2012 15:27:39 door Jan R
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
SELECT
someone
FROM
sometable
WHERE
CONCAT(
YEAR(CURDATE()),'-',MONTH(CURDATE()),'-',DAY(CURDATE())
BETWEEN
(CURDATE() - INTERVAL 2 WEEK)
AND
(CURDATE() + INTERVAL 2 WEEK)
someone
FROM
sometable
WHERE
CONCAT(
YEAR(CURDATE()),'-',MONTH(CURDATE()),'-',DAY(CURDATE())
BETWEEN
(CURDATE() - INTERVAL 2 WEEK)
AND
(CURDATE() + INTERVAL 2 WEEK)
Even los uit de pols
Edit:
te los dus
te los dus
Aangepast, maar of het nou sneller/korter is???
Toevoeging op 01/09/2012 15:47:50:
Maar wel beter overigens, want volgens jouw methode met DAYOFYEAR ben ik als het schrikkeljaar is op 21 juli (nog niet) jarig
Toevoeging op 01/09/2012 16:03:53:
Hmz, dat "beter" moet ik ook weer terugnemen, want de mijne werkt ook niet goed an het begin en einde van het jaar.
Gewijzigd op 01/09/2012 15:44:36 door Ger van Steenderen
Code (php)
1
2
3
4
5
6
2
3
4
5
6
SELECT username, user_id, FROM_UNIXTIME(user_gebdate) AS geboortedatum
FROM phpbb_users
WHERE FROM_UNIXTIME( user_gebdate )
BETWEEN (NOW( ) - INTERVAL 1 DAY )
AND (NOW( ) + INTERVAL 1 DAY )
ORDER BY user_gebdate
FROM phpbb_users
WHERE FROM_UNIXTIME( user_gebdate )
BETWEEN (NOW( ) - INTERVAL 1 DAY )
AND (NOW( ) + INTERVAL 1 DAY )
ORDER BY user_gebdate
Lijkt heel erg veel op bovenstaande code, maar filtert gelijk op alleen gisteren/vandaag/morgen.
Code (php)
1
2
3
4
2
3
4
SELECT geb_datum
FROM tabel
WHERE DAYOFYEAR(geb_datum)-DAYOFYEAR(CURDATE()) BETWEEN 0 and 14
OR DAYOFYEAR(geb_datum)-DAYOFYEAR(CURDATE())+365 < 14
FROM tabel
WHERE DAYOFYEAR(geb_datum)-DAYOFYEAR(CURDATE()) BETWEEN 0 and 14
OR DAYOFYEAR(geb_datum)-DAYOFYEAR(CURDATE())+365 < 14
De tweede heb je nodig om de gevallen rond de jaarwisseling aan te pakken. Wil je het helemaal correct doen zou je eigenlijk nog moeten corrigeren voor schrikkel jaren overigens.
Als ik ben geboren op 1 september 1964 wordt ik in jouw query never nooit geselecteerd.
PS
Een goede lezer weet nu mijn geboortedatum
Je bedoelt dat je van voor de UNIX-timestamp bent? Ja, maar dat hebben we gefixt door iedereen standaard 50 jaar ouder te laten zijn :mrgreen:
Komt omdat heel phpBB met timestamps werkt ipv de (veel betere) datetime. 't Was ook maar een opzetje ;).
PS op www.zunflappie.nl/temp/alle_data.sql krijg je alle data tussen 1-1-1970 en 31-12-2070. Ik heb die al tabel in mijn database staan om dit soort dingen te krijgen.
Want als je op 21-8-2012 geen artikelen hebt, wat toon je dan...? Niets? Een leeg vak (voor 21 augustus)? etc. Dit kan handig zijn.
Ik heb al heel wat kritiek gehad hierop, maar tot nu toe nog geen snellere/simpelere manier gevonden om in MYsql zoiets te krijgen.
Gewijzigd op 01/09/2012 17:13:16 door Eddy E
Maar kijk gewoon even naar je eigen query, want die werkt gewoon niet
Toevoeging op 01/09/2012 17:51:32:
PS
Ik heb even op die link van jou geklikt, en het is dat ik zit, anders lmoa
Een tabel maken met alle mogekijke datums?????????????
Toevoeging op 02/09/2012 12:28:58:
Zie hieronder
Gewijzigd op 02/09/2012 19:26:55 door Ger van Steenderen
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
function GetDateList($forward, $backward=0) {
if (is_int($forward) && is_int($backward)) {
$now_in_days = floor(time() / 86400);
$start_date = ($now_in_days - $backward) * 86400;
$end_date = ($now_in_days + $forward) * 86400;
$date_range = array();
while ($start_date <= $end_date) {
$date_range[] = date('m-d', $start_date);
$start_date += 86400;
}
return "('" . implode("','", $date_range) . "')";
}
return false;
}
$sql = "SELECT
username
FROM
usertable
WHERE
DATE_FORMAT('%m-%d', birthdate)
IN
" . GetDateList(14,14);
?>
function GetDateList($forward, $backward=0) {
if (is_int($forward) && is_int($backward)) {
$now_in_days = floor(time() / 86400);
$start_date = ($now_in_days - $backward) * 86400;
$end_date = ($now_in_days + $forward) * 86400;
$date_range = array();
while ($start_date <= $end_date) {
$date_range[] = date('m-d', $start_date);
$start_date += 86400;
}
return "('" . implode("','", $date_range) . "')";
}
return false;
}
$sql = "SELECT
username
FROM
usertable
WHERE
DATE_FORMAT('%m-%d', birthdate)
IN
" . GetDateList(14,14);
?>
Handig als je alle eerste zondagen van de maanden wilt hebben. Of alle werkdagen in week 28 van jaar 2053 bijvoorbeeld. Maar er is een heel topic aan gewijd op PHPhulp hier, dus ga ik niet te veel uitwijden.
Gewijzigd op 04/09/2012 09:06:37 door Eddy E
Het is een gezamelijk oplossing van Eddy en Ger geworden. een beetje sql en een beetje php :)
Jan
Dan gebruik je daar een andere query dan die hier staat.
Stel, iemand is geboren op 1 september 1983, je krijgt dan uit de query die je hier geplaatst hebt:
Als jij een database gebruikt voor het opslaan van algemene logica, dan gebruik je de database verkeerd.
@Jan,
Hoe heb je het nu opgelost dan?
Gewijzigd op 02/09/2012 20:49:35 door Ger van Steenderen
Ik krijg in mijn query niets uit 1983, maar alleen van gisteren, vandaag en morgen. Maar daar gaat het niet om. Jan R heeft zijn antwoord, en met behulp van jouw en mijn query is dat blijkbaar gelukt. Mooi toch?
Maar de vraagstelling was hoe de jarigen in een tijdsspanne te selecteren, en daar werkt jouw query niet voor.
Gewijzigd op 02/09/2012 21:01:43 door Ger van Steenderen
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
include ("opendb.php");
$dayNumber = date("z") + 1 ;
$query = "SELECT voornaam ,
achternaam as naam,
DATE_FORMAT(geboortedatum, '%d-%m-%Y') AS datum
FROM postleden where ((DATE_FORMAT(geboortedatum, '%d-%m-%Y') <> '01-01-1920')
and ";
$query .= "(DAYOFYEAR(geboortedatum)-DAYOFYEAR(CURDATE()) BETWEEN -7 and 14)";
if ($dayNumber<15 || $dayNumber>350){
$query .= " OR ((DAYOFYEAR(geboortedatum)-DAYOFYEAR(CURDATE())+365) < 14)";
}
$query .= ")";
$result = mysql_query($query);
if (!$result)
{
die('<br>Fout: ' . mysql_error());
}
$first=false;
while(list($vnaam,$anaam, $datum)= mysql_fetch_row($result))//, $dts,$v
{
if (!$first)
{
$first=true;
$terug = "gelukkige verjaardag aan: ";
}
else
{
$terug .= ", ";
}
$terug .= "$vnaam $anaam ($datum)";
}
if ($terug!=""){
echo 'document.write(\'<br><br><div style=\"color:blue ; background-color:yellow ; font-size:15pt\">'.$terug.'</div>\')';
}
mysql_close($con);
?>
include ("opendb.php");
$dayNumber = date("z") + 1 ;
$query = "SELECT voornaam ,
achternaam as naam,
DATE_FORMAT(geboortedatum, '%d-%m-%Y') AS datum
FROM postleden where ((DATE_FORMAT(geboortedatum, '%d-%m-%Y') <> '01-01-1920')
and ";
$query .= "(DAYOFYEAR(geboortedatum)-DAYOFYEAR(CURDATE()) BETWEEN -7 and 14)";
if ($dayNumber<15 || $dayNumber>350){
$query .= " OR ((DAYOFYEAR(geboortedatum)-DAYOFYEAR(CURDATE())+365) < 14)";
}
$query .= ")";
$result = mysql_query($query);
if (!$result)
{
die('<br>Fout: ' . mysql_error());
}
$first=false;
while(list($vnaam,$anaam, $datum)= mysql_fetch_row($result))//, $dts,$v
{
if (!$first)
{
$first=true;
$terug = "gelukkige verjaardag aan: ";
}
else
{
$terug .= ", ";
}
$terug .= "$vnaam $anaam ($datum)";
}
if ($terug!=""){
echo 'document.write(\'<br><br><div style=\"color:blue ; background-color:yellow ; font-size:15pt\">'.$terug.'</div>\')';
}
mysql_close($con);
?>
Momenteel werkt alles. Ik hoop gewoon dat het rond nieuwjaar ook goed werkt. indien niet zoeken we weer verder :)
In Access is het wel eenvoudiger. Daar heb je:
Jan
Gewijzigd op 02/09/2012 21:27:49 door Jan R
Iemand die op 18 september in een niet-schrikkeljaar is geboren, wordt nu meegeselecteerd. Ik gebruik geen DAYOFYEAR omdat het geen constant gegeven is.
Overigens heb ik er ooit eens een sproc voor gemaakt, maar die kan ik niet meer zo snel terugvinden.
kan je hier meer duidelijkheid verstrekken?
18/9 is toch een gewone dag?
Jan
Zonder gekheid, in een schrikkeljaar schuiven de dagen na februari met DAYOFYEAR een dag op. Dus dat betekent, omdat dit jaar een schrikkeljaar is, we op dag 247 leven ipv 246.
Andersom is dat ook, als iemand in een schrikkeljaar geboren is, dan is dat ook weer een andere dag in een niet-schrikkeljaar.
Daarnaast heb je aan het eind van het jaar altijd een probleem met het sorteren, wat voor mij eigenlijk de voornaamste reden gewwest is om het in stored procedure op te lossen.
Gewijzigd op 03/09/2012 20:05:06 door Ger van Steenderen
Rare uitkomsten en complexe berekeningen ontkom je dus eigenlijk nooit aan.
Je kan ze niet opeens een dag eerder of later als jarig neerzetten.,
Volledig akkoord dat er een extra dag is. maar sortering is bij mij nu niet belangrijk en een test wees toch uit dat 31-12-2012 dag 366 is. Ik heb wel niet getest op 18-9 :)
Pietje is geboren op 19-09-1985 (DOY 262)
Dus als je nu vandaag jouw query uitvoert wordt Pietje wel geselecteerd maar Jantje niet, gevolg:
Jantje:
Hé, hoe kan dat nou? Ik ben op dezelfde dag jarig als Pietje, maar ik sta er niet bij!
Ik weet, het is sex met mieren, maar ik zou dat willen voorkomen.
En als je dat wilt, kan je eigenlijk al niet meer met DAYOFYEAR werken, want dan krijg je heel complexe IF en/of CASE constructies.