Avatar billede henrik_r Nybegynder
07. december 2005 - 00:53 Der er 20 kommentarer og
1 løsning

Fødselsdag

Hej - jeg har en tabel, indeholdende navn og fødsesldato.

Eks.

Henrik  1985-06-13
Jakob    1985-04-07

osv.. Der er ca. 20 - 30 personer i den..

Jeg ønsker, at lave en SQL sætning, der giver flg. kolonner tilbage:

1. Navn
2. Alder de bliver
3. Fødselsdag i dag? (1 hvis sand, 0 hvis falsk)

Listen skal være sorteret efter hvem der næste gang har fødselsdag, og der skal vises 5 relationer.

Jeg har prøvet lidt med noget order by date, og noget limit 0,5 men jeg må indrømme jeg er ved at være lidt lost..

Nogen som lige hurtigt kunne hjælpe? Kunne være nice..

På forhånd tak for hjælpen..

M.v.h.
Henrik Rasmussen
Avatar billede sbahn Nybegynder
07. december 2005 - 23:41 #1
select navn, year(NOW())-year(fdag), CEIL(day(NOW())-day(fdag)/365) as dage from tabel order by dage limit 5;
...eller noget i den stil. Jeg er lidt usikker på om det hedder day(); håber det hjælper dig i gang i det mindste.
Avatar billede henrik_r Nybegynder
08. december 2005 - 10:41 #2
Hmm.. Har leget lidt med det..

Har fået den til at vælge to måneder nu. Men problemet er så, hvordan jeg skal sortere dem.. Altså i where delen står der bare, at month(birtday) skal være lig denne måned, eller næste måned.

Men så bliver der et sorteringsproblem. Og hvis det er lige her ved årsskifte, skal den jo lægge en til alderen og sådan lidt..

Det er vist ikke så nemt at knække denne nød.

Mvh. Henrik
Avatar billede fixxxer Nybegynder
08. december 2005 - 11:32 #3
Den her ser ud til at virke.. (og det var bestemt ikke nogen nem nød at knække)

SELECT navn,
IF(
    MONTH(NOW()) > MONTH(birthday) AND DAY(NOW()) > DAY(birthday),
        YEAR(NOW())-YEAR(birthday)-1,
            IF(MONTH(NOW()) > MONTH(birthday),
                YEAR(NOW())-YEAR(birthday)-1,
                    IF(MONTH(NOW()) = MONTH(birthday) AND DAY(NOW()) > DAY(birthday),
                        YEAR(NOW())-YEAR(birthday)-1,
                        YEAR(NOW())-YEAR(birthday)-1
                    )
            )
) AS age,
IF(
    NOW() = birthday,
        1,
        0
) AS is_birthday
FROM profiler
Avatar billede fixxxer Nybegynder
08. december 2005 - 11:37 #4
Der var en lille bøf..


SELECT navn,
IF(
    MONTH(NOW()) > MONTH(birthday) AND DAY(NOW()) > DAY(birthday),
        YEAR(NOW())-YEAR(birthday)-1,
            IF(MONTH(NOW()) > MONTH(birthday),
                YEAR(NOW())-YEAR(birthday)-1,
                    IF(
                        MONTH(NOW()) = MONTH(birthday) AND DAY(NOW()) < DAY(birthday),
                            YEAR(NOW())-YEAR(birthday)-1,
                            YEAR(NOW())-YEAR(birthday)
                    )
            )
) AS age,
IF(
    NOW() = birthday,
        1,
        0
) AS is_birthday
FROM profiler
Avatar billede jimjimjam Nybegynder
08. december 2005 - 11:39 #5
Følger lige med her! :)
Avatar billede henrik_r Nybegynder
08. december 2005 - 11:53 #6
Tester det lige i aften..

Men det ser godt nok vildt ud :)

Men tak for hjælpen..
Avatar billede henrik_r Nybegynder
08. december 2005 - 13:42 #7
Har prøvet at køre den - men synes ikke rigtig den giver noget der giver mening desværre :(

Får bare alle navne ud og en alder (som ikke passer :) )
Skulle jo helst kun være dem der har fødselsdag inden for de næste XX dage. 30 eller sådan noget..

Men vidste ikke man kunne bruge if i sql sætninger.. Så dem vil jeg lige lege lidt med og så finde ud af om jeg kan finde ud af det..

Men spørgsmålet er, om det bliver en lidt for avanceret sætning. Det var en sætning jeg vil have på forsiden af min hjemmeside, og den skulle helst ikke bruge for mange kræfter..

Jeg har fået den til at virke med en måned af gangen.


    SELECT
        name,
        (YEAR(CURRENT_DATE)-YEAR(birthday)) AS age,
        dayofmonth(birthday) as day,
        month(birthday) as month,
        year(current_date) as year,
        (month(birthday)=month(current_date) and dayofmonth(birthday)=dayofmonth(current_date)) as today
    FROM members
WHERE MONTH(birthday) = MONTH(CURRENT_DATE)
AND DAYOFMONTH(birthday)>=DAYOFMONTH(CURRENT_DATE)
ORDER BY DAYOFMONTH(birthday)
LIMIT 0,5
Avatar billede fixxxer Nybegynder
08. december 2005 - 14:20 #8
Det nævnte du ikke noget om i det omringelige beskrivelse :)

Helt præcist hvad er det du vil opnå?


Jeg har skrevet og testet SQL'en på en tabel med et date-felt, hvis du bruger et andet felt til at skrive fødselsdatoer ind, forstår jeg godt at det ikke virker..

Hvad angår performence tror jeg ikke at det er noget som er tungt for MySQL databasen.. den er ret sej sådan en :)
Avatar billede henrik_r Nybegynder
08. december 2005 - 17:59 #9
Fra første post:

"Listen skal være sorteret efter hvem der næste gang har fødselsdag, og der skal vises 5 relationer." :)

Jeg har i min database en tabel indeholdende:
navn : varchar(50)
fødseldag : date

over nogle personer..

Fødselsdagen er givet som YYYY-MM-DD (eksempelvis som 1985-12-11)

Det jeg så gerne vil have min SQL spytter ud er en liste, som skal vises på forsiden af hjemmesiden, som en "Næste fødselsdage" rubrik.

hvori der står Eks.

28.12.05: Morten - 22 år
13.01.06: Jesper - 23 år
17.01.06: Kasper - 22 år
04.02.06: Jakob - 19 år
13.02.06: John Doe - 30 år

Det store problem er at få det lavet så det virker her omkring nytår.. Omkring nytår bliver der et problem med hvordan man skal sortere dem. Fra eksemplet ovenover har jeg svært ved at få Morten til at stå øverst..

Håber det er blevet lidt klarere nu..

Har ledt meget rundt på nettet.. Kan ikke forstå, hvorfor der ikke er andre der har haft brug for det samme.. :)

Men mange tak for din hjælp..
Mvh. Henrik
Avatar billede showsource Seniormester
09. december 2005 - 04:48 #10
Den er lidt kringlet.
Hvis nu der ikke er nogen som har fødselsdag indenfor de næste 30 dage?
Eller hvis kun 1 har det?

Men et stykke af vejen, er vist noget i stil med: (med php)

<?php
$nu = date("m-d");
echo"\$nu == ". $nu ."<p>";

$fremtid = date("m-d", strtotime("+20 days"));
echo"\$fremtid == ". $fremtid;

if($fremtid < $nu) {
$search_operator = "OR";
}else{
$search_operator = "AND";
}

echo"<hr>";

$c = mysql_query("SELECT * FROM `birth` WHERE DATE_FORMAT(birthday, '%m-%d') >= '". $nu ."' ". $search_operator ." DATE_FORMAT(birthday, '%m-%d') <= '". $fremtid ."' ORDER BY `birthday`") or die (mysql_error());

while($vis = mysql_fetch_object($c)) {
echo"<p>". $vis->navn ." - ". $vis->birthday ."<br />";
}

mysql_free_result($c);
?>
Avatar billede showsource Seniormester
09. december 2005 - 04:59 #11
Og forresten, lidt trist at UNIX_TIMESTAMP kun går tilbage til 1-1-1970 :O)
Avatar billede henrik_r Nybegynder
09. december 2005 - 08:51 #12
Rigtigt lækker svar :)

Nåede også til noget der lignede lidt det der i går :)

Men problemet er, at nu får jeg godt nok de næste ud der har fødselsdag..

Men lad os sige, at vi i dag kigger 30 dage frem (dvs. 09-01-06)..

Så er der en der har fødselsdag ex. den 15-12-05 og en som har 03-01-06.. Så bliver ham med fødselsdag den 03-01-05 vist først :(

Kan ikke lige gennemskue hvordan man kan fixe det.. Overvejer en eller anden løsninger, hvor man i sql'en laver "noget sql AS nextbirthday" og så order by nextbirthday :)

Tusind tak for hjælpen..

Mvh Henrik
Avatar billede showsource Seniormester
09. december 2005 - 10:12 #13
Ja, ved sgutte om der er noget mysql som kan det. Bl.a. også at vise den nye alder.

Men hvis den ældste vises først.

$c = mysql_query("SELECT * FROM `birth` WHERE DATE_FORMAT(birthday, '%m-%d') >= '". $nu ."' ". $search_operator ." DATE_FORMAT(birthday, '%m-%d') <= '". $fremtid ."'  ORDER BY  DATE_FORMAT(birthday, '%Y') ASC LIMIT 0,5") or die (mysql_error());

Men evt. lægge resultat i et array, og så lave noget PHP som "styrer" output :O)
Avatar billede henrik_r Nybegynder
09. december 2005 - 10:17 #14
Jeps.. Må jeg prøve...

Smid et svar..
Avatar billede showsource Seniormester
09. december 2005 - 10:26 #15
Man kan jo bruge mktime() og sortere på den.
Så skal man blot finde ud af om det er i det nye år der er fødslesdag

Den her returnerer den aktuelle alder

function age($var) {

    $nu = date("Y-m-d");
    $split1 = explode("-", $var);
    $split2 = explode("-", $nu);

        if($split2[1] . $split2[2] >= $split1[1] . $split1[2]) {
        $antal_aar = ($split2[0]-$split1[0]);
        }else{
        $antal_aar = (($split2[0]-$split1[0])-1);
        }

    return $antal_aar;

}
Avatar billede showsource Seniormester
09. december 2005 - 15:12 #16
Det er altså noget rod, det her!
Men hvis du HØJEST går en måned frem, kan det gøres med ORDER BY

$c = mysql_query("SELECT * FROM `birth` WHERE DATE_FORMAT(birthday, '%m-%d') >= '". $nu ."' ". $search_operator ." DATE_FORMAT(birthday, '%m-%d') <= '". $fremtid ."' ORDER BY DATE_FORMAT(birthday, '%m') DESC, DATE_FORMAT(birthday, '%d') ASC LIMIT 0,7") or die (mysql_error());
Avatar billede showsource Seniormester
09. december 2005 - 15:16 #17
hmmm, skal jo så nok være 28 dage højest?
Altså, hvis dato er d. 31-01, og der er 1 som har dag i februar, men 10 andre i marts, så springes februar jo over :O)
Avatar billede showsource Seniormester
09. december 2005 - 15:46 #18
nåh, det er sgu da osse noget vrøvl!
Altså, hvis man er i januar, så vil februar blive vist først :O)
Avatar billede showsource Seniormester
10. december 2005 - 12:44 #19
Bare lige, og stadig vil det kun virke for hvis det er denne og næste måned.
Ikke over flere måneder

$dagefrem = 28; // antal dage der kikkes fremad

$nu = date("m-d"); // Lige nu, måned og dag

$fremtid = date("m-d", strtotime("+". $dagefrem ." days")); // fremtid, måned og dag

if($fremtid < $nu) { // f.eks. 01-05 < 12-10
$search_operator = "OR";
$m_sort = "DESC"; // SORTERING FOR MÅNED
}else{
$search_operator = "AND";
$m_sort = "ASC"; // SORTERING FOR MÅNED
}

$dage = mysql_query("SELECT `navn`,`birthday`, DATE_FORMAT(birthday, '%d-%m') as `visdato` FROM `birth` WHERE DATE_FORMAT(birthday, '%m-%d') >= '". $nu ."' ". $search_operator ." DATE_FORMAT(birthday, '%m-%d') <= '". $fremtid ."' ORDER BY DATE_FORMAT(birthday, '%m') ". $m_sort .", DATE_FORMAT(birthday, '%d') ASC LIMIT 0,5") or die (mysql_error());
Avatar billede henrik_r Nybegynder
10. december 2005 - 17:45 #20
Tusind tak for hjælpen.. Nu har jeg fået det til at virke med 28 dage frem..
Rigtig nice!

Her kommer lige den endelige kode.
---------------------------------------------------------------------------

$dagefrem = 28; // antal dage der kikkes fremad

$nu = date("m-d"); // Lige nu, måned og dag

$fremtid = date("m-d", strtotime("+". $dagefrem ." days")); // fremtid, måned og dag

if($fremtid < $nu) { // f.eks. 01-05 < 12-10
  $search_operator = "OR";
  $m_sort = "DESC"; // SORTERING FOR MÅNED
} else {
  $search_operator = "AND";
  $m_sort = "ASC"; // SORTERING FOR MÅNED
}

$sqlbirth = "
  SELECT
    id,
    `name`,
    `birthday`,
    (YEAR(CURRENT_DATE)-YEAR(birthday)) AS `age`,
    DATE_FORMAT(birthday, '%d-%m') as `visdato`,
    dayofmonth(birthday) as day,
    month(birthday) as month,
    month(current_date) as thismonth,
    year(current_date) as year,
    (month(birthday)=month(current_date) and
        dayofmonth(birthday)=dayofmonth(current_date)) as today
 
  FROM `members`
 
  WHERE DATE_FORMAT(birthday, '%m-%d') >= '". $nu ."' ". $search_operator ."
                              DATE_FORMAT(birthday, '%m-%d') <= '". $fremtid ."'

  ORDER BY DATE_FORMAT(birthday, '%m') ". $m_sort .", DATE_FORMAT(birthday, '%d') ASC
    LIMIT 0,5
";


$resultbirth = mysql_query($sqlbirth) or die (mysql_error());

while($rowB = mysql_fetch_array($resultbirth)) {
  if($rowB['month']<$rowB['thismonth']) {
    $alder = $rowB['age'] + 2;
    $year = $rowB['year'] + 1;
  } else {
    $alder = $rowB['age'] + 1;
    $year = $rowB['year'];
  }

  echo "$rowB[day].$rowB[month].$year - $rowB[name] - $alder år<br />";
}
Avatar billede showsource Seniormester
10. december 2005 - 18:03 #21
En lidt anden ver. _O)

<?php

$dagefrem = 28; // antal dage der kikkes fremad

$nu = date("m-d"); // Lige nu, måned-dag

$fremtid = date("m-d", strtotime("+". $dagefrem ." days")); // fremtid, måned-dag

if($fremtid < $nu) { // f.eks. 01-05 < 12-10
$search_operator = "OR";
$m_sort = "DESC"; // SORTERING FOR MÅNED
}else{
$search_operator = "AND";
$m_sort = "ASC"; // SORTERING FOR MÅNED
}

echo"Nu == ". $nu ."<br>";
echo"Slut = ". $fremtid;


echo"<hr>";

$dage = mysql_query("SELECT `navn`, DATE_FORMAT(`birthday`, '%m-%d') as `dato`, DATE_FORMAT(`birthday`, '%d-%m') as `visdato`, (YEAR(NOW())-YEAR(`birthday`)) as `alder` FROM `birth` WHERE DATE_FORMAT(`birthday`, '%m-%d') >= '". $nu ."' ". $search_operator ." DATE_FORMAT(`birthday`, '%m-%d') <= '". $fremtid ."' ORDER BY DATE_FORMAT(`birthday`, '%m') ". $m_sort .", DATE_FORMAT(`birthday`, '%d') ASC LIMIT 0,5") or die (mysql_error());

    if(mysql_num_rows($dage) != 0) {
    $text = "";
        while($vis = mysql_fetch_object($dage)) {

            if($m_sort == "DESC" && $vis->dato <= $fremtid) {
            $aar = ($vis->alder+1);
            }else{
            $aar = $vis->alder;
            }

        $text .= $vis->navn ." fylder ". $aar ." &aring;r ";

            if($vis->dato == $nu) {
            $text .= "i dag! :O)<br />\r\n";
            }else{
            $text .= "d. ". $vis->visdato ."<br />\r\n";
            }
        }
    echo $text;
    }

mysql_free_result($dage);

?>
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester