Avatar billede jedimaster Nybegynder
31. marts 2010 - 10:10 Der er 18 kommentarer og
1 løsning

Searchscript med output tabel.

Hej Eksperter.

Jeg har en mysql database til en slags biblioteksdatabase indeholdende blandt andet følgende tabeller og variable:

-BOG-
[id]
[titel]
[aargang]
[forlag]
[isbn]

-EMNE-
[id]
[emnenavn]
[bog_id]

-FORFATTER-
[id]
[forfatternavn]
[bog_id]

Som I måske kan se, er "hovedtabellen" BOG. Her bliver de informationer der kun optræder en gang lagret. Da hver bog godt kan være inden for flere emner (nogle to emner andre fem) og da hver bog kan være skrevet af flere forfattere, har jeg oprettet tabellerne EMNE og FORFATTER. De refererer så til "hovedtabellen" ved bogens ID.

Spørgsmålet er nu, hvordan laver jeg en søgefungtion hvor der søges i alle data (dog ID undtaget) og hvor output-tabellen er noget lign.:

| titel | forfattere | årgang | forlag | emner | isbn |

Hver bog skal naturligvis kun angives en gang i output. Dvs. hvis jeg søger på bogens titel, skal der ikke komme 5 x bogen frem fordi der er fem forfattere.

P.F.T.

/JediMaster
Avatar billede dkfire Nybegynder
31. marts 2010 - 11:38 #1
Har du taget højde for at en forfatter kan have skrevet flere bøger ?
Og et emne kan passe til flere bøger ?
Avatar billede jedimaster Nybegynder
31. marts 2010 - 12:29 #2
Ja. Jeg har tidligere lavet en ekstra tabel som sammenholdt bog_id og forfatter_id samt bog_id og emne_id. Men jeg blev anbefalet at lave ovenstående, da det ville sløve en søgeproces meget ned - men det er måske ikke tilfældet??
Avatar billede jedimaster Nybegynder
31. marts 2010 - 12:31 #3
Undskyld.

Det ville naturligvis sløve processen af have flere tabeller der sammenholdt bog_id med forfatter_id/emne_id end mit udgangspunkt i nærværende spørgsmål.

Men du kan måske foreslå noget andet?
Avatar billede dkfire Nybegynder
31. marts 2010 - 12:58 #4
Jeg kan ikke se at det skulle sløve din søgning at have normaliseret din database struktur.
Jeg ville anbefale dig at have to tabeller som kobler dine bøger sammen med henholdsvis forfatter og emne, da du har en "mange til mange" relation.
Avatar billede jedimaster Nybegynder
31. marts 2010 - 14:13 #5
OK - det kan jeg godt følge dig i (det korresponderer da også med min barnelærdom).

Forudsætningerne er nu at jeg har følgede tabeller;

-BOG-
[id]
[titel]
[aargang]
[forlag]
[isbn]

-EMNE-
[id]
[emnenavn]


-FORFATTER-
[id]
[forfatternavn]

-EMNEBOG- (der sammenkobler)
[bog_id]
[emne_id]

-FORFATTERBOG-
[forfatter_id]
[emne_id]
31. marts 2010 - 23:03 #6
Jeg har vaeret udenbys idag.  Eftersom denne traad ikke synes at have naaet en konklusion og ikke har haft friske indlaeg i adskillige timer tillader jeg mig at bryde ind.

Da jeg, udlandsdansker, engang i et tidligere aarhundrede boede i Danmark, var der en sang "Har du glemt din barnetro?"  der blandt andet sagde at "barnetro - til himmelen du er en gylden bro."  Findes den sang stadig?

Hvad jeg vil anbefale er at du holder dig til din barnelaerdom, normaliserede tabeller, som du udtrykker i #5 med den undtagelse at tabellen FORFATTERBOG skal have felterne forfatter_id og bog_id.

Saa faar du dit output "| titel | forfattere | årgang | forlag | emner | isbn |" ved hjaelp af foelgende sql query:

SELECT titel, forfatternavn, aargang, forlag, emne, isbn
FROM BOG b
JOIN FORFATTERBOG fb ON b.id = fb.bog_id
JOIN FORFATTER f ON fb.forfatter_id = f.id
JOIN EMNEBOG eb ON b.id = eb_bog_id
JOIN EMNE e ON eb.emne_id = e.id

Den query giver dig en linje for hver kombination af bog/forfatter/emne.  Hvis en bog har to forfattere og tre emner faar du seks forskellige linjer der alle ti naevner bogens titel, aargang, forlag, og isbn.  Det er nu engang naturen af relationelle databaser.

Hvis du vil have et output saasom:

"Bog1 Forfatter1 Forfatter2 2007 Forlag1 Emne1, Emne2 "

saa maa du tage din query ud i en applikation, for eksempel en php-side, og programmere den til at presentere et saadan output.
Avatar billede dkfire Nybegynder
02. april 2010 - 00:22 #7
Grunden til jeg ikke har skrevet skyldes til dels at jeg ikke har så meget andet at byde på lige nu, samt tiden er knap for mig.

Men jeg fald da lige over et andet spørgsmål som kan hjælpe dig det sidste stykke vej.
http://www.eksperten.dk/spm/905989
Svar #20 giver dig et link til en funktion i mysql som opfylder det du gerne vil.
02. april 2010 - 16:43 #8
jedimaster, saa du mit indlaeg?  I haab om at det var til nytte sender jeg dette som svar.  Hvis det ikke virkede eller hvis jeg har misforstaaet problemet saa forklar saa jeg kan proeve at forbedre.

Til dkfire:  den traad du henviser til konkluderede ogsaa at skoent det er muligt at tviste nogle sql dialekter til speciel formattering saa er saadan formattering opgaven for den applikation hvor resultatet af sql queryen traekkes ud.
Avatar billede dkfire Nybegynder
03. april 2010 - 00:17 #9
Christian_Belgien:
Tror ikke helt du har læst hele tråden igennem.
Det svar jeg henviser til viser netop en funktion til mysql som kan give det ønskede dataset ud.
At du så synes det er applikation som skal gøre det, er jeg personligt ikke så meget interesseret i. Det er mere op til OP at afgøre.
OP ønskede en måde at trække information ud på, med et bestemt format, det er så der at den anden tråd evt. kan hjælpe.
Hvis mysql kan hjælpe ham/hende med at give sådan et dataset, er det vel den bedste løsning. Hvordan han/hun vælger at præsentere det for brugen vil jeg ikke tage stilling til.
Avatar billede jedimaster Nybegynder
05. april 2010 - 10:24 #10
Jeg har nu forsøgt mig Christian_Belgiens query, og den fungerer. Jeg har ikke forsøgt mig med Group_Concat() endnu.

Hvis jeg anvender Christian_Belgiens svar, er mit output er dog stadig ikke helt som jeg ønsker det.

Nogen ide til at lave en PHP kode der gør det ønskede, således at alle forfattere der er tilknyttet en bog vises i samme række - eksempelvis med et komma i mellem (og det samme for emne)?

Tak for svar indtil videre.
05. april 2010 - 19:48 #11
Jeg er i gang, men det varer nok en god times tid fordi der er noget jeg skal foerst.
05. april 2010 - 20:56 #12
Saa er jeg med igen.

Jeg ved ikke hvor meget du kender til PHP.  En normal fremgangsmaade er foerst at stille queryen ($result = mysql_query("SELECT ...."), derefter at tage resultatet ud raekke for raekke ved (while($row = mysql_fetch_array($result)) echo $row['titel'] . ", " . $row['forfatternavn'] . ", " $row['aargang']) o.s.v.

Men paa den maade faar du en output linie for hver query-resultat-raekke, altsaa for hver kombination af titel og forfatter.  Det var ikke det du ville have.  Hvad jeg derfor har gjort er dette:

Hvis titlen er den samme som titlen i den foregaaende raekke skriver jeg det nye forfatternavn paa den bestaaende output linie.  Hvis titlen har aendret sig laver jeg en ny output linie og skriver titel, aargang, forfatter, o.s.v.

Af dovenskab har jeg placeret forfatternavnet/navnene til sidst, og jeg ignorerede muligheden for at en bog ogsaa kunne have mere end en titel, men ved at udvide eksemplet kan det ogsaa lade sig goere.

For at teste min kode oprettede jeg tabellerne og fyldte nogle vaerdier i.  Mit PHP output var dette.  Jeg haaber det svarer til hvad du er ude efter.  Hvis ikke, saa har jeg ikke forstaaet dig og du maa forklare yderligere.

Titel: titel1, Aargang: 2001, Forlag: forlag1, Emne: emnenavn2, ISBN: isbn1, Forfattere: forfatter1, forfatter2, forfatter3
Titel: titel2, Aargang: 2002, Forlag: forlag2, Emne: emnenavn2, ISBN: isbn2, Forfattere: forfatter3
Titel: titel3, Aargang: 2003, Forlag: forlag3, Emne: emnenavn1, ISBN: isbn3, Forfattere: forfatter3

Her er min kode (med connection- og password details skjult): 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <title></title>
</head>

<body>
<?
$link = mysql_connect ('xxxx', 'yyyy', 'zzzz') or die(mysql_erorr());
mysql_select_db('qqqq') or die('Could not select database');

$result = mysql_query("SELECT titel, forfatternavn, aargang, forlag, emnenavn, isbn
FROM bog b
JOIN forfatterbog fb ON b.id = fb.bog_id
JOIN forfatter f ON fb.forfatter_id = f.id
JOIN emnebog eb ON b.id = eb.bog_id
JOIN emne e ON eb.emne_id = e.id
ORDER BY titel, forfatternavn
");
$titel = "";
while($row = mysql_fetch_array($result))
{
  if($row['titel'] <> $titel)
  {
    $titel = $row['titel'];
    echo "<br/>Titel: " . $row['titel'] . ", Aargang: " . $row['aargang'] . ", Forlag: " . $row['forlag'] . ", Emne: " . $row['emnenavn'] . ", ISBN: " . $row['isbn'] . ", Forfattere: " . $row['forfatternavn'];
  }
  else echo ", " . $row['forfatternavn'];
}
mysql_close($link); 
?> 
</body>
07. april 2010 - 21:09 #13
jedimaster, jeg er spaendt paa din reaktion til det indlaeg jeg sendte for to dage siden.  Er det et brugbart svar paa spoergsmaalet?  Eller har jeg misforstaaet, i saafald forklar venligst yderligere.
Avatar billede jedimaster Nybegynder
10. april 2010 - 21:20 #14
Hej Christian_Belgien.

Så er jeg på igen - og er ked af ventetiden. Jeg er kun amatør programmør, og har mit daglige virke i en helt anden boldgade. Desværre har jeg ikke haft tid til at se på dit svar før nu - men jeg ser på det og vender naturligvis tilbage i morgen.

Vh
Jedimaster
10. april 2010 - 21:55 #15
Det er noteret.  Tak for feed-back.
Avatar billede jedimaster Nybegynder
11. april 2010 - 19:37 #16
Hey.

Jeg har siddet og rodet lidt med det. Lige et opklarende spørgsmål, skal der ikke være en WHERE betingelse i query'et?

/Jedimaster
11. april 2010 - 20:20 #17
Der skal kun vaere en WHERE betingelse hvis du vil soege paa noget bestemt saasom paa et bestemt emne.  Men det handlede dit spoergsmaal ikke om.  Du sagde:  "Spørgsmålet er nu, hvordan laver jeg en søgefungtion hvor der søges i alle data ..."

Men hvis du vil soege efter et bestemt emne (for eksempel) kan du putte emnet i en variable $emne og bruge denne query:

$emne = "emnenavn2";
$result = mysql_query("SELECT titel, forfatternavn, aargang, forlag, emnenavn, isbn
FROM jedi_bog b
JOIN jedi_forfatterbog fb ON b.id = fb.bog_id
JOIN jedi_forfatter f ON fb.forfatter_id = f.id
JOIN jedi_emnebog eb ON b.id = eb.bog_id
JOIN jedi_emne e ON eb.emne_id = e.id
WHERE emnenavn = '$emne'
ORDER BY titel, forfatternavn
");
o.s.v.
Avatar billede jedimaster Nybegynder
12. april 2010 - 07:59 #18
Til Christian_Belgien:

Jeg har forsøgt mig med din kode til generering af flere forfattere ud fra hver bog, og det fungerer helt fint. Tror jeg vil bygge det lidt anderledes op, men ideen (som jeg ikke selv kunne finde) er smart.

Med hensyn til WHERE betingelsen, har jeg måske ikke været specifik nok - men det skal du ikke lide under i pointgivningen. Mit spørgsmål var netop at man skulle kunne søge i alle felter - fx. ved forfatternavn, titel, emne etc. - og få en liste som angivet i mit første spørgsmål. På samme måde som når man søger ex. det kongelige bibliotek. Jeg går ud fra, at jeg så blot skal have en masse WHERE xx like '%$search%' OR yy like '%$search%'.

Under alle omstændigheder har du fortjent point - idet dine forslag har hjulpet mig videre.
12. april 2010 - 09:01 #19
Ok, saa afgiver du points og lukker spoergsmaalet (please).
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
Vi tilbyder markedets bedste kurser inden for webudvikling

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