Avatar billede page Nybegynder
17. november 2012 - 14:15 Der er 15 kommentarer og
1 løsning

joine 3 tabeller

Hej,

jeg har 3 tabeller, tabel 1, tabel2 og tabeljoin. Lidt interamistisk så ser tabellerne sådan her ud:

tabel1
id1
text1
status1
-------
tabel2
id2
text2
status2
--------
tabeljoin
joinid
id1
id2

Og det jeg forsøger, er at joine dem, således at den i een sætning vælger hvor enten det ene, eller det andet er muligt:
(tabel1.id1 = tabeljoin.id1 AND tabel1.status1 = '1') OR (tabel2.id2 = tabeljoin.id2 AND tabel2.status2= '1')


Håber det giver mening :)

Jeg har forsøgt med en INNER JOIN, men det vil ikke give mig noget resultat :(

$sql ="SELECT tabel1.*, tabel2.*, tabeljoin.*
FROM tabel1
INNER JOIN tabeljoin ON tabel1.id1=tabeljoin.id1
INNER JOIN tabel2 ON tabeljoin.id2=tabel2.id2
WHERE tabel1.status1='1' OR tabel2.status2='1' ORDER BY tabeljoin.joinid";

Har i nogle forslag? og kan det overhovedet lade sig gøre?

mvh
page
Avatar billede erikjacobsen Ekspert
17. november 2012 - 16:39 #1
Den sidste giver god mening for mig. Det afhænger dog af hvad der står i dine tabeller - kan du give et eksempel på indhold?
Avatar billede page Nybegynder
17. november 2012 - 16:49 #2
Hej Erik,

Jeg har lavet det som et eksempel for ikke at skulle skrive "alt" indhold i tabellen.

Meningen er at jeg skal joine de to tabeller i forhold til en kalender.
Dvs. at den ene tabel bruger jeg til at holde styr på en slags aktiviteter og den anden tabel en anden slag saktiviteter. De har forskellige behov i forhold til række udseendet, derfor har jeg oprettet hver deres tabel.

Og så en join tabel hvor jeg håber at kunne kører dem sammen.

status - er enten 0 eller 1, alt efter om indholdet skal vises på siden eller ej.
id - er blot et fortløbende nummer. 1, 2, 3, 4, osv.
text - Indeholder noget tekst.

Grundet status afgør om indholdet skal vises eller ej, er det vigtigt for mig at få den med i WHERE sætningen.
Avatar billede erikjacobsen Ekspert
17. november 2012 - 16:53 #3
Det er fint du ikke skriver alle detaljer. Ud fra din beskrivelse kan jeg komme i tvivl om join giver mening. Men et eksempel passende til det neddroslede eksempel kan godt give mening... ;)

Meget generelt: man joiner to tabeller, der har "forskelligt" indhold og et id tilfælles, men dine aktiviteter synes at have "samme" indhold.
Avatar billede page Nybegynder
17. november 2012 - 17:06 #4
Jeg syntes nu det gav god mening det jeg skrev :D

Jeg har tænkt på om, jeg istedet skal gøre det, at når jeg ændre status til 0/1 så tilføjes fjernes den fra tabeljoin, og på den måde kan jeg styre hvad der vises på siden. Det er i hvertfald et alternativ hvis jeg ikke kan lave det i en sætning :)
Avatar billede erikjacobsen Ekspert
17. november 2012 - 17:38 #5
Jeg er ikke overbevist .... :)  Eksempler ftw!

tabel1
1 kartoffelsalat 1
2 ananas 1
3 jordbær 0

tabel2
1 julemanden 1
2 gollum 0
3 andersand 1

Hvad kan din jointabel indeholde, og hvad skal udskrives?
17. november 2012 - 18:26 #6
Vi har halvvejs aftalt andetsteds, at jeg skulle komme ind.  I mellemtden er erikjacobsen igang med at udtrykke de samme tanker jeg fik da jeg kikkede på spørgsmålet.  Jeg har på fornemmelsen (og erik vist også) at problemet ligger i at strukturere dine data.  Hvis du har to typer aktiviteter, så er den gængse løsning at lave en enkelt tabel for aktiviteter med et ekstra felt for type.  Så kan du, efter behov, søge efter aktiviteter type 1 status 1 særskilt fra aktiviteter type 2 status 1. 

Men det er dig der spørger om hjælp.  Hvis du ikke er interesseret i at give flere oplysninger, så kommer vi nok ikke videre.  Det at det for dig giver god mening hjælper ikke så meget.
Avatar billede page Nybegynder
18. november 2012 - 15:26 #7
tabel1
1 julemarked 1
2 arbejdsweekend 0
3 fællesmad 0

tabel2
1 tur til fyn 1
2 tur til norge 1
3 tur til gurre 0

Grunden til at jeg lavede dem i to tabeller er, at de godt nok har det til fælles at de skal med i kalenderen, men der er lidt forskel på mængden af information.

Jeg har copy/pastet mine tabeller her:

CREATE TABLE IF NOT EXISTS `tblKalender` (
  `kalenderID` int(6) NOT NULL AUTO_INCREMENT,
  `overskrift` text NOT NULL,
  `beskrivelser` text NOT NULL,
  `emne` text NOT NULL, <--- denne definere hvilken type fælles aktivitet der er tale om
  `dato` text NOT NULL,
  `usdato` text NOT NULL,
  `status` text NOT NULL,
  PRIMARY KEY (`kalenderID`)
)

CREATE TABLE IF NOT EXISTS `tblBustur` (
  `busturID` int(3) NOT NULL AUTO_INCREMENT,
  `tur` text NOT NULL,
  `pladser` int(3) NOT NULL,
  `dato` text NOT NULL,
  `usdato` text NOT NULL,
  `pris` text NOT NULL,
  `kommentar` text NOT NULL,
  `status` text NOT NULL,
  `type` text NOT NULL,  <--- Denne definere om det er med tog/bus/cykel/ben/bil
  PRIMARY KEY (`busturID`)
)

CREATE TABLE IF NOT EXISTS `tblKalenderJoin` (
  `kjID` int(9) NOT NULL AUTO_INCREMENT,
  `kID` text NOT NULL,
  `bID` text NOT NULL,
  `usdato` text NOT NULL,
  PRIMARY KEY (`kjID`)
)



Jeg kan godt se at de måske kunne samles i en tabel, men jeg syntes nu der rarest at have dem særskilt.
Avatar billede erikjacobsen Ekspert
18. november 2012 - 15:36 #8
men "julemarked" har ikke noget med "tur til fyn" at gøre, ud over at de har samme id, vel? Derfor ikke join.

Hvis du vil have dem i 2 tabeller, så laver du 2 select-sætninger.

Felter med datoer bør være af typen DATE.
Avatar billede page Nybegynder
18. november 2012 - 16:10 #9
nej de har ikke noget med hinanden at gøre, og er derfor ikke en join.

Men med to select sætninger, vil jeg vel først kører den ene tabel igennem og så den anden efterfølgende?

Jeg ville gerne at de kom ud, sorteret efter usdato (2012.11.18).

Derfor lavede jeg tblKalenderJoin der med kalenderID = kID og busturID = bID og usdato, kan lave sorteringen. Er det helt forkert tænkt?
18. november 2012 - 19:45 #10
Hvad er det du vil have skrevet ud?  Er det simpelt hen en liste af alle aktiviteter i tblKalender og i tblBustur med status = 1, i dato rækkefølge?    Måske er det UNION du have fat i.  Med UNION kan man få et enkelt resultat fra søgning i flere tabeller.  Så skal søgningen struktureres, så de to delresultater bruger kolonner med ens datatype i samme rækkefølge.

Med den antagelse, at du følger rådet i #8 og omstrukturerer tabellerne så datoer (og usdato) får datatypen DATE, så konstaterer jeg, at du i Kalender har en id, fire tekster overskrift, beskrivelse, emne, status, og to datoer, dato og usdato.  I tblBustur har du også id og fire tekster, tur, kommentar, type, og status, og to datoer, og derudover en int for pladser og en txt for pris.

Så burde du kunne få dit resultat således (ikke testet):

SELECT id, overskrift, beskrivelse, emne, dato, usdato, status, "", ""
FROM tblKalender
WHERE status = 1
UNION
SELECT id, tur, kommentar, type, dato, usdato, status, pladser, pris
FROM tblBustur
WHERE status = 1
ORDER BY dato

Hvis det er noget andet du vil have skrevet ud, så forklar hvad det er.
Avatar billede erikjacobsen Ekspert
18. november 2012 - 21:04 #11
Det tror jeg ikke lige man kan, Christian. En UNION kræver ens felter.

Men i betragtning af de seneste oplysninger vil jeg foreslå den simple løsning: alt i een tabel, og så et par NULL-værdier. Jeg mener at kunne se, at antal rækker ikke overstiger 100 (pr år), og så er vi i mikro-afdelingen.

Hvad med ca disse felter:

ID, type, overskrift, beskrivelser, emne, dato, status, pris, kommentar

typen siger bus/tog/.../arrangement og bestemmer så hvilken af de følgende felter, der skal indeholde værdier. Resten er bare NULL.

Du skal kun have een dato, af typen DATE, men når du viser den på siden, så konverterer du den lige til fx.  18. november 2012.
18. november 2012 - 22:14 #12
erikjacobsen, med de oplysninger vi har om tabellernes indhold ville jeg afgjort placere alle aktiviteter i en enkelt tabel, hvis jeg skulle have designet databasen.  tblKalender og tblBustur har parallelt indhold bortset fra, at busture har felter for pladser og pris.  (Nogle af de 'parallele' felter i de to tabeller har forskellige navne, men det ville kunne rettes til.)  Så langt er vi enige.

Men det er jo spørgsmålsstilleren der definerer problemstillingen.  Der er allerede blevet foreslået at placere alle aktiviteter i en enkelt tabel, men det blev afvist.  Spørgsmålsstilleren er ude efter en løsning med to forskellige tabeller for aktiviteter.  Det har jeg så forholdt mig til og foreslået en UNION løsning.  Det virker faktisk!  Jeg har lige testet det af.  (Fra de indlæg jeg i tidens løb har set fra dig er det mig klart, at din generelle viden overstiger min.  Hvad angår UNION tror jeg du definerer det for snævert.  Felterne må ikke 'konflikte' således at hvis for eksempel det tredje felt i det første subquery er en varchar kan tredje felt i en anden subquery ikke være en int.  Men bortset derfra behøver felterne ikke at være ens.  Hvis det fjerde felt i første subquery er tomt kan det fjerde felt i andet subquery, ifølge mine tests, godt være en int.)

Men en tblKalenderJoin synes under alle omstændigheder at være overflødig.  Der er ikke nogen 'mange-til-mange' relationer mellem aktiviteter i de to tabeller.
Avatar billede erikjacobsen Ekspert
18. november 2012 - 22:18 #13
Mysql tillader en del, der ikke er standard. Jeg skal ikke lige kunne sige om dette er en af den slags.
Avatar billede page Nybegynder
19. november 2012 - 07:48 #14
Det er helt korrekt at jeg blot vil have en liste. Som du, Christian, skriver i #10
Og hvis i mener det giver fordel at ligge tabellerne sammen i een, så vil jeg gøre det...

Som i selv nævner det, så er strukturen nærmest ens, men jeg havde forestillet mig at det var smartere at have dem adskilt i to tabeller, så jeg ikke fik NULL felter. I er begge enige om at det ikke er den mest optimale løsning jeg jeg kommet frem til mht. strukturen. Og det vil jeg tage til mig.

Bare af nysgerrighed, hvorfor ville du(Christian) droppe tblKalenderJoin? hvis jeg beholder dem i to tabeller, så ville det eneste måde jeg kunne knytte dem på, vel være med en join tabel?

Eller det overflødigt fordi jeg alligevel bare henter dataen, og ikke ser på om de har relationer i join tabellen?
19. november 2012 - 09:12 #15
page, når man sætter en database op, så skal man sætte tabeller op efter hvilken struktur ens data har, hvordan de afhænger af hinanden.  Man skal på dette stadie se bort fra hvordan man bagefter vil trække data ud.  Trække data ud, det gør man i forespørgslerne, og hvis man har givet tabellerne den rigtige struktur, så kan man trække data ud på alle tænkelige måder, også på måder man ikke havde tænkt på da man satte databasen op.

For dine kalenderbegivenheder/busture er det således (efter hvad du har vist os) at hver begivenhed står alene, er ikke afhængig af andre data elementer, og der er ingen dataelementer afhængig af en kalenderbegivenhed.  Sådanne data placerer man i en enkelt tabel.

Tag så eksemplet hvor begivenheder har underdele, for eksempel at en bustur stopper ved pyramiderne, derefter ved Grand Canyon, og til slut ved Peterskirken (det er en lang bustur).  Så er der en 'en-til-mange' relation mellem begivenheder og underdele.  Hver begivenhed kan have mange underdele, hver underdel hører til en bestemt begivenhed.  Så laver man en tabel for begivenheder og en tabel for underdele, og i tabellen for underdele laver man et felt 'begivenhed' med id'en for den pågældende begivenhed.

Endnu et eksempel:  Man vil definere begivenhederne i kategorier, måske for at kunne søge.  Lad os sige du som kategorier har busture, karnevaller, virksomhedsbesøg, ungdomsrejser, kulturelle ture, o.s.v.  En bustur med en ungdomsgruppe hvor man besøger Vikingeskibs musæets afdeling der restaurerer bådene kan kategoriseres som bustur, ungdomsrejse, virksomhedsbesøg, og kulturel tur.  Der er så en 'mange-til-mange' relation mellem begivenheder og kategorier.  Hver begivenhed kan høre til mange kategorier, og i hver kategori er der mange begivenheder.  Det er for sådanne 'mange-til-mange' relationer man laver tabeller som din tblKalenderJoin der viser hvilke kombinationer af begivenheder og kategorier der er.

Men som sagt, begivenhederne i tblKalender og begivenhederne i tblBustur afhænger ikke af hinanden.  Det er ikke således, at der til hver tblKalender begivenhed knyttes mange tblBustur begivenheder og der til hver tblBustur begivenhed kører mange tblKalender begivenheder.  Hvis du i en database forespørgsel vil have dataudtræk fra flere tabeller, så definerer du det i forespørgslen, ikke i den måde du sætter tabellerne op.

Jeg har lavet en illustration af disse tre tilfælde som du kan se på http://christianjorgensen.be/Page.PNG, øverst tilfældet med ture der hver især står alene, derefter et tilfælde med udeflugter der har underdele, og til sidst et tilfælde med trips i kategorier.

Jeg fandt også et link på dansk om normalisering, http://www.designcreative.dk/?page=normalisering

Jeg opretter dette indlæg som et svar, idet jeg skønner, at vi er ved at have udtømt emnet.
Avatar billede page Nybegynder
19. november 2012 - 10:25 #16
Tak for forklaringen, det er super. Og det giver helt klar stof til eftertanke hvis jeg senere skal lave noget lignende.

Jeg syntes database opbygningen og strukturen hertil er superspændende, men jeg vælger så ikke altid den rette løsning.. endnu :)

I skal begge have tak for at få mig på "rette" vej i forhold til at opbygningen.

Christian du få alle point, da jeg ved at Erik ikke samler på dem. Men i skal begge have mange tak for inputtet.
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