Hjælp til forespørgsel

Tags:    databaser

Howdy...

hvem kan knække denne :

Jeg har 3 tabeller.

Tabel 1:
id v1 v3 v2
1 1 12 bla
2 1 Null vfk

Tabel 2:
id vt1 vt2 vt3
1 12 asd 23
2 78 sadas 34
3 32 asda 56

Tabel 3:
id vt2 vt3
1 23 sdfsd
2 23 etrer
3 23 34234

Vil gerne udtrække alle poster fra tabel 1 hvor v1 = 1 og de poster i tabel2 hvor v3 = vt1 og blot vt3 fra den første post i tabel 3 hvor vt3 = vt2.

Altså skal forespørgslen returnere 2 poster.

Hvem kan knække den ??

/Anders



9 svar postet i denne tråd vises herunder
2 indlæg har modtaget i alt 4 karma
Sorter efter stemmer Sorter efter dato
En god måde at starte på er ved at forestille sig problemet UDEN afgrænsninger, dvs i dette eksempel skal vi forbinde 3 tabeller:

"Udtræk alle poster fra tabel1"
select * from tabel1

"tilføj de tabeller der også indgår i eksemplet"
select * from tabel1, tabel2, tabel3

"lav begrænsninger - første: v1=1"
select * from tabel1, tabel2, tabel3 where tabel1.v1=12

"lav begrænsninger - anden: v3=v1"
select * from tabel1, tabel2, tabel3 where tabel1.v1=12 and tabel2.v3=tabel1.v1

"lav begrænsning - tredje: v3=v2"
select * from tabel1, tabel2, tabel3 where tabel1.v1=12 and tabel2.v3=tabel1.v1 and tabel3.v3 = tabel2.v2

Undskyld min lidt længere forklaring, men det er nemmere at man selv forstår det, hvis man skal udbygge det senere.

P.S. kig på hvilke kolonner du skal bruge, det er ikke sikkert at det er korrekt med en "select *", specielt ikke når du joiner flere andre tabeller på, måske var det bedre med: "select tabel1.v1, tabel1.v2.... from ...."





Indlæg senest redigeret d. 14.10.2008 13:42 af Bruger #2730
SELECT DISTINCT...

eller

SELECT .... GROUP BY tabel1.navn

resten ser jo meget rigtigt ud...



Nu er der forskelligt antal kolonner i hver tabel, så hvad vil du have fra hver ?

Du kan bruge union til at tilføje flere forespørgsler og få et samlet resultat men de enkelte forespørgsler skal returnere samme antal kolonner.

select stuff from tabel1 where something=7 union
select other_stuff from tabel2 where something_else=3 union
select different_stuff from tabel3 where this=6;



Problemet med Roberts løsning er at den ikke krydser dem, du får ikke foreningsmængden, dvs dem som BÅDE er 7 i tabel 1, OG som linker mod tabel2 OG som linker på tabel3.

i stedet får du den fra tabel1 som er =7, og dem fra tabel2 der er =3 og dem fra tabel3 der er =6.. dvs. der er ikke joinet på nøgler...

Det kan være at det er det du har behov for, så er det den løsning du vælger. Men vær opmærksom på forskellen.

Dvs du får fællesmængden i stedet for foreningsmængden.

http://en.wikipedia.org/wiki/Union_(set_theory)
http://en.wikipedia.org/wiki/Intersection_(set_theory)

Min løsning er den nederste, Roberts løsning er den øverste.







Indlæg senest redigeret d. 14.10.2008 13:53 af Bruger #2730
Synes jeg har skitseret hvad jeg ønsker, men prøver at præcisere lidt nærmere.

Tabel 1:
id v1 v3 v2
1 1 12 bla
2 1 Null vfk

Tabel 2:
id vt1 vt2 vt3
1 12 asd 23
2 78 sadas 34
3 32 asda 56

Tabel 3:
id vt2 vt3
1 23 sdfsd
2 23 etrer
3 23 34234

min forespørgsel skal returnere noget der ligner :
1,1,12,bla,asd,23,sdfsd
1,2,null,null,null,null,null

fungerer fint med left outer join mellem tabel 1 og tabel 2 - alle poster fra tabel 1 returnes og findes der matches indsættes værdierne fra tabel 2 ellers blot null.
problemet består i at få tilføjet værdien af blot det første match imellem tabel 2 og 3.
Hvis der anvendes normalt join kommer en masse næsten ens poster hvor blot værdien af indholdet i tabel 3 varierer.



Problemet med Roberts løsning er at den ikke krydser dem, du får ikke foreningsmængden


Absolut, men jeg forstår heller ikke helt, hvad Anders vil :)

Hvis tabellerne og kolonnerne havde lidt mere sigende navne var det nok til at gætte sig frem.

Endnu en god lektie i at bruge sigende navne.



Indlæg senest redigeret d. 14.10.2008 14:35 af Bruger #2695
Så du vil kun have et enkelt resultat fra tabel 3?
således den i dit eksempel ikke fanger alle 3 rækker med værdien '23' men kun den første? Hvis det er tilfældet kan du ikke bruge en select * da den matcher alle. Måske skal du lave en subselect for at få den øverste række fra tabel 3...



Præcis Brian nu nærmer vi os...

denne select :
SELECT tabel1.navn, tabel3.tlfnummer, tabel2.pris1, tabel2.pris2
FROM tabel1 LEFT OUTER JOIN
tabel2 ON tabel1.navneid = tabel2.navneid LEFT OUTER JOIN
tabel3 ON tabel2.ydelse = tabel3.ydelse
WHERE (tabel1.boksid = 250)

returnerer dette :
Peter 1000439 1695 1440
Peter 1000445 1695 1440
Peter 1000448 1695 1440
Peter 1000449 1695 1440
Søren 1995 1663
Hans 1000450 2395 1988
Hans 1000451 2395 1988
Hans 1000452 2395 1988
Mads 1295 1072
Jens 3295 2782

numrene i kolonne 2 kommer fra tabel 3.

jeg ønsker dog blot værdien af den første fundne post således at navnerækkefølgen bliver unik.



SELECT DISTINCT...

eller

SELECT .... GROUP BY tabel1.navn

resten ser jo meget rigtigt ud...


får heller ikke det til at virke da der er Ntext felter i tabellen..



t