Avatar billede showsource Seniormester
16. november 2008 - 11:34 Der er 32 kommentarer og
1 løsning

Søgning i en tabel ( lottotal )

Hej
Jeg har en tabel:

CREATE TABLE `vindertal` (
  `dato` date NOT NULL default '0000-00-00',
  `one` int(2) unsigned NOT NULL default '0',
  `two` int(2) unsigned NOT NULL default '0',
  `three` int(2) unsigned NOT NULL default '0',
  `four` int(2) unsigned NOT NULL default '0',
  `five` int(2) unsigned NOT NULL default '0',
  `six` int(2) unsigned NOT NULL default '0',
  `seven` int(2) unsigned NOT NULL default '0',
  `til_et` int(2) unsigned NOT NULL default '0',
  `til_to` int(2) unsigned default NULL,
  `sum_et` int(11) unsigned default NULL,
  `sum_to` int(11) unsigned default NULL,
  `vinder_et` int(2) unsigned default NULL,
  `vinder_to` int(2) unsigned default NULL,
  UNIQUE KEY `dato` (`dato`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

som indeholder alle lottotrækninger.

Hvis nu jeg vil hente de rows hvor f.eks. 12 og 27 er udtrukket, hvordan gør jeg så det nemmest ?
Avatar billede showsource Seniormester
16. november 2008 - 13:16 #1
Hmm, nu har jeg en lidt anden bøf:

F.eks. vil flg vise en række: ( Nogle af tallene fra i går )

SELECT * FROM `vindertal` WHERE
(`one` = 5 OR `two` = 5 OR `three` = 5 OR `three` = 5 OR `four` = 5 OR `six` = 5 OR `seven` = 5)
AND
(`one` = 16 OR `two` = 16 OR `three` = 16 OR `three` = 16 OR `four` = 16 OR `six` = 16 OR `seven` = 16)
AND
(`one` = 18 OR `two` = 18 OR `three` = 18 OR `three` = 18 OR `four` = 18 OR `six` = 18 OR `seven` = 18)
AND
(`one` = 20 OR `two` = 20 OR `three` = 20 OR `three` = 20 OR `four` = 20 OR `six` = 20 OR `seven` = 20)
ORDER BY `dato` DESC

Men ryger der et tal mere i, så finder den ingen rækker ?

SELECT * FROM `vindertal` WHERE
(`one` = 5 OR `two` = 5 OR `three` = 5 OR `three` = 5 OR `four` = 5 OR `six` = 5 OR `seven` = 5)
AND
(`one` = 16 OR `two` = 16 OR `three` = 16 OR `three` = 16 OR `four` = 16 OR `six` = 16 OR `seven` = 16)
AND
(`one` = 18 OR `two` = 18 OR `three` = 18 OR `three` = 18 OR `four` = 18 OR `six` = 18 OR `seven` = 18)
AND
(`one` = 20 OR `two` = 20 OR `three` = 20 OR `three` = 20 OR `four` = 20 OR `six` = 20 OR `seven` = 20)
AND
(`one` = 23 OR `two` = 23 OR `three` = 23 OR `three` = 23 OR `four` = 23 OR `six` = 23 OR `seven` = 23)
ORDER BY `dato` DESC
Avatar billede arne_v Ekspert
16. november 2008 - 15:05 #2
Du vaelger ned bedre tabel struktur !!

traekning
  id
  dato
  ...

vindertal:
  traekningid
  boldnr

og saa laver du:

SELECT dato
FROM (vindertal vt1 JOIN traekning ON vt1.traekningid=traekning.id)
    JOIN vindertal vt2 ON vt2.traekningid=traekning.id
WHERE vt1.boldnr=12 AND vt2.boldnr=27
Avatar billede showsource Seniormester
16. november 2008 - 15:35 #3
Ja, jeg har også tænkt over hvordan den ellers skulle bygges op, men er ikke lige kommet på noget.

vindertal => Så kommer der et traekningid for hvert nummer ( 7 ) som trækkes ?
D.v.s.en trækning, 7 rows ?
Avatar billede arne_v Ekspert
16. november 2008 - 15:44 #4
for hver 1 raekke i traekning kommer der 7 raekker i vindertal

(find selv ud af noget for tillaegstal)
Avatar billede showsource Seniormester
16. november 2008 - 15:57 #5
Det prøver jeg lige af.
Avatar billede showsource Seniormester
16. november 2008 - 16:59 #6
Nåh, der er noget jeg ikke fatter!
Har nu flg. tabeller:

CREATE TABLE `traekninger` (
  `id` int(11) NOT NULL auto_increment,
  `dato` date NOT NULL,
  `sum_et` int(10) unsigned NOT NULL default '0',
  `sum_to` int(10) unsigned NOT NULL default '0',
  `vinder_et` int(10) unsigned NOT NULL default '0',
  `vinder_to` int(10) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `dato` (`dato`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

og

CREATE TABLE `udtrukne` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `datoid` int(10) unsigned NOT NULL,
  `nummer` int(10) unsigned NOT NULL,
  `tillaeg` int(1) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

Når jeg prøver flg:

$find = "SELECT dato
FROM (udtrukne vt1 JOIN traekninger ON vt1.datoid=traekninger.id)
    JOIN udtrukne vt2 ON vt2.datoid=traekninger.id
WHERE vt1.nummer=12 AND vt2.nummer=27 AND vt2.tillaeg=0";


Men, hvorfor vt1 i WHERE ?
Avatar billede showsource Seniormester
16. november 2008 - 17:00 #7
Og ja, prøver jeg med vt2, så finder en ikke nogen! :O)
Avatar billede arne_v Ekspert
16. november 2008 - 17:10 #8
CREATE TABLE `udtrukne` (
  `traekningid` int(10) unsigned NOT NULL auto_increment,
  `nummer` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

$find = "SELECT dato
FROM (udtrukne vt1 JOIN traekninger ON vt1.traekningid=traekninger.id)
    JOIN udtrukne vt2 ON vt2.traekningid=traekninger.id
WHERE vt1.nummer=12 AND vt2.nummer=27";
Avatar billede arne_v Ekspert
16. november 2008 - 17:11 #9
Du skal finde den række i traekning som har både en række i udtrukne med 12 og en anden
række i udtrukne med 27.
Avatar billede showsource Seniormester
16. november 2008 - 17:17 #10
Jeg er godt mok lidt rundt på gulvet her!
Dit ex. med CREATE TABLE, skal der ikke være en ref for traekninger?

Hmm, og jeg ved jo ikke altid hvor mange tal jeg skal finde der matcher

12,27
5,13,24,32

.....
Avatar billede arne_v Ekspert
16. november 2008 - 17:21 #11
traekningid er FK til traekninger tabellen

hvis du søger efter N tal så skal du have N-1 joins
Avatar billede arne_v Ekspert
16. november 2008 - 17:25 #12
ups

PRIMARY KEY  (`traekningid`, `nummer`)
Avatar billede showsource Seniormester
16. november 2008 - 17:28 #13
Well, jeg var en gang nummer 2 på fyn i 100 meter butterfly, og den træning må jeg vist hellere lige ta' op, for jeg har det som jeg skal krydse atlanten.

"hvis du søger efter N tal så skal du have N-1 joins"
Den er jeg ikke med på det?
Avatar billede arne_v Ekspert
16. november 2008 - 17:40 #14
Jeg kunne engang svømme 1000 m på en lille time ...

:-)

Det er heller ikke helt rigtigt.

Du skal joine traekning med N-1 kopier af udtrukne.

Så leder du efter 2 tal skal du joine traekning, vt1, vt2 og leder du efter 3 tal
skal du joine traekning, vt1, vt2, vt3.
Avatar billede showsource Seniormester
16. november 2008 - 17:46 #15
Ja, jeg kan garanteret nå at svømme de første kilometer inden jeg har fattet en løsning på query til det her!

Men du må gerne smide et svar, jeg er ikke i tvivl om at jeg er blevet ledt på rette spor, det skal bare lige sætte sig ordentligt fast i min malerhjerne!
Avatar billede arne_v Ekspert
16. november 2008 - 20:07 #16
Jeg lavede fejl igen.

Du skal joine traekning med N kopier af udtrukne.

Det er nok nemmere at se med data.

traekning:

1  8-Nov-2008
2  15-Nov-2008

udtrukne:

1 2
1 5
1 9
1 18
1 23
1 29
1 39
2 11
2 17
2 22
2 23
2 31
2 32
2 35

SELECT dato
FROM (traekning JOIN udtrukne u1 ON traekning.id=u1.id)
    JOIN udtrukne u2 ON traekning.id=u2.id
WHERE u1.nummer=11 AND u2.nummer=22

vil finde 15-Nov-2008 fordi at den query vil joine følgende 3 rækker:

traekning = 2  15-Nov-2008
u1 = 2 11
u2 = 2 22
Avatar billede arne_v Ekspert
16. november 2008 - 20:07 #17
og et svar
Avatar billede showsource Seniormester
16. november 2008 - 20:17 #18
ahh, tror jeg blev lidt klogere, men flg. er hvad jeg fik skrevet inden jeg havde set du postede:


hmm, jeg tror jeg skal spille syvkabale resten af aftenen!

Jeg har nu tre tabeller:

CREATE TABLE `lottotraekninger` (
  `id` int(11) NOT NULL auto_increment,
  `dato` date NOT NULL,
  `sum_et` int(10) unsigned NOT NULL default '0',
  `sum_to` int(10) unsigned NOT NULL default '0',
  `vinder_et` int(3) unsigned NOT NULL default '0',
  `vinder_to` int(3) unsigned NOT NULL default '0',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `dato` (`dato`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;


CREATE TABLE `lottotal` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `datoid` int(10) unsigned NOT NULL,
  `nummer` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

CREATE TABLE `lottotillaegstal` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `datoid` int(10) unsigned NOT NULL,
  `nummer` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;


Jeg har så en side, ( php ) med mulighed for at indtaste talkombinationer så man kan se hvor ofte det/de tal er blevet udtrukket.

Ved submit, bruger jeg flg. til at få at array med tal.

if(isset($_GET["find_nr"])) {

$numbers = array();

    for($i = 1; $i < 8; $i++) {
        if(isset($_GET["comb_".$i]) && false != ($nr = (int)$_GET["comb_".$i])) {
            if($nr < 37) {
            $numbers[] = $nr;
            }
        }

    }


$numbers = array_unique($numbers);
sort($numbers);
$antal = count($numbers);

    if($antal > 0) {

    // Her vil jeg gerne ha' en "dynamisk" query, ud fra det/de tal som findes i $numbers


    }

}

Men jeg fatter hat af "Du skal joine traekning med N-1 kopier af udtrukne"

Smider meget gerne max point hvis du kan vise et ex.
Avatar billede arne_v Ekspert
16. november 2008 - 20:29 #19
Jeg prøver lige at bixe noget simpelt.

Jeg nægter at lave tillægs tal !
Avatar billede showsource Seniormester
16. november 2008 - 20:31 #20
tillægstal blev også smidt i en tabel for sig, for de må ryge på en anden formular! :O)
Avatar billede arne_v Ekspert
16. november 2008 - 20:51 #21
MySQL:

CREATE TABLE lottotraekning (
  trid INTEGER NOT NULL AUTO_INCREMENT,
  dato DATE NOT NULL,
  PRIMARY KEY (trid)
);

CREATE TABLE lottotal (
  trid INTEGER NOT NULL,
  nummer INTEGER NOT NULL,
  PRIMARY KEY  (trid, nummer)
);

INSERT INTO lottotraekning(dato) VALUES('2008-11-8');
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 2);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 5);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 9);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 18);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 23);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 29);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 39);
INSERT INTO lottotraekning(dato) VALUES('2008-11-15');
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 11);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 17);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 22);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 23);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 31);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 32);
INSERT INTO lottotal VALUES(LAST_INSERT_ID(), 35);
Avatar billede arne_v Ekspert
16. november 2008 - 20:51 #22
PHP:

<form method="POST">
Numre (adskilt af komma): <input type="TEXT" name="numre">
<br>
<input    type="SUBMIT" value="Søg">
</form>
<?php
if(isset($_POST['numre'])) {
    $numre = explode(",", $_POST['numre']);
    $joins = '';
    $wheres = '';
    for($i = 1; $i <= count($numre); $i++) {
        $nummer = $numre[$i-1];
        $joins .= " JOIN lottotal tal_$i ON lottotraekning.trid = tal_$i.trid";
        $wheres .= " AND tal_$i.nummer=$nummer";
    }
    $sql = "SELECT dato FROM lottotraekning $joins WHERE true $wheres";
    //print $sql . "<br>\n";
    $con = mysql_connect("localhost", "root", "") or die(mysql_error());
    mysql_select_db("Test", $con) or die(mysql_error());
    $query = mysql_query($sql, $con) or die(mysql_error());
    print "Datoer:\n";
    print "<ul>\n";
    while($row = mysql_fetch_array($query)) {
        print "<li>" . $row['dato'] . "\n";
    }
    print "</ul>\n";
    mysql_close($con);
}
?>
Avatar billede showsource Seniormester
16. november 2008 - 21:01 #23
Hvad skulle vi dog gøre uden dig arne?
Takker rigtig mange gange!!!!!!
Avatar billede showsource Seniormester
16. november 2008 - 21:18 #24
He, den er godt nok langsom, hvis jeg prøver med tre tal.
Og med fire går det helt galt.

Er det mangel på indexes?
Avatar billede arne_v Ekspert
16. november 2008 - 21:57 #25
Sikkert.

Prøv med index på:

lottotal.trid
lottotal.nummer
Avatar billede showsource Seniormester
16. november 2008 - 22:22 #26
well, lidt læsning i manual:
"If a table has 1,000 rows, this is at least 100 times faster than reading sequentially."

Den der "at least" kan vist godt omformuleres til 1000 :O)
Avatar billede showsource Seniormester
16. november 2008 - 22:38 #27
Og hov, 4 km. km jeg ca. op, men forståelsen er nok kun på 80% :O)
Avatar billede arne_v Ekspert
16. november 2008 - 22:56 #28
Det hjalp med index ?
Avatar billede showsource Seniormester
16. november 2008 - 23:11 #29
Ja for sa... da, den kommer med det samme!
( Hvilket man ikke kan sige om min logiske sans )
Avatar billede arne_v Ekspert
17. november 2008 - 00:06 #30
Inden du betragter koden som færdig, skal du lige have noget data validering
lagt ind til at beskytte dig mod SQL injection - det er jo dynamisk SQL !
Avatar billede showsource Seniormester
17. november 2008 - 05:37 #31
jow jow, jeg bruger det array ( $numbers ) som jeg viste kode til tidligere
Avatar billede showsource Seniormester
05. juni 2009 - 21:01 #32
Det er også blevet til en webside!
www.lottostatistik.dk
Avatar billede showsource Seniormester
05. juni 2009 - 21:02 #33
ups, men der er klumper på nettet på vej hertil, så det er ikke altid at der er svar!
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