Avatar billede joemoz Nybegynder
08. juni 2009 - 14:49 Der er 18 kommentarer

SQL query med en linje pr. nøgleværdi

Jeg har brug for lidt hjælp til en SQL query.

Jeg har tre tabeller, lad os kalde dem tabel1, tabel2 og tabel3, som er bundet sammen af en fælles nøgle, lad os kalde den key1

tabel1 og tabel2 har en én-til-én relation med hinanden, hvorimod tabel3 har en mange-til-en relation med dem.

Jeg ønsker at lave en query hvor der kun er en entry pr. key1-værdi - uanset hvor mange gange den optræder i tabel3.

Hvis jeg laver en query der hedder

select tabel1.vaerdi1, tabel2.vaerdi2, tabel3.vaerdi3 from tabel1,tabel2,tabel3 where tabel1.key1=tabel2.key1 and tabel1.key1=tabel3.key1 where tabel3.vaerdi3='ABC'

får jeg en liste hvor der er lige så mange entries som der er records med tabel3.vaerdi3='ABC'  . Hvordan kan jeg lave den så der kun er en række pr. key1-værdi?

Håber det giver mening.
Avatar billede j3ppah Novice
08. juni 2009 - 14:58 #1
Du skal bruge DISTINCT i din select på tabel1
Avatar billede j3ppah Novice
08. juni 2009 - 14:58 #2
Hov, ikke på tabel 1, på din key1 selvfølgelig
Avatar billede joemoz Nybegynder
08. juni 2009 - 15:33 #3
Tak men jeg synes ikke rigtig den giver det ønskede resultat - jeg får stadig flere af den samme værdi fra tabel1. Kan du specificere yderligere hvordan querien skal laves?
Avatar billede Syska Mester
08. juni 2009 - 23:34 #4
Problemet som jeg ser det er at du har en 1 til mange mellem table2 og table3 ...

Du kan ikke bruge DISTINCT da table3 værdier ikke nødvendigvis er UNIQUE som jeg har forstået det.

måske noget ala:
SELECT ID, * FROM table2
INNER JOIN
( SELECT MAX(ID) FROM table3 GROUP BY key1 ) as dt1 -- giver en divered table med højeste nyeste id, gruperet af din key1
ON table2.ID = dt1.ID

Jeg er ikke sikker på dine ID's ... men ideen skulle være der :-)

Håber du kan løse de eventuelle fejl jeg har lavet i overstående :-)

// ouT
Avatar billede arne_v Ekspert
09. juni 2009 - 02:44 #5
Dørste spørgsmål er: du har 1 række i tabel1 som matcher 1 række i tabel2 som matcher 7 rækker i tabel3 - hvilket kriterie skal bruges for at udvælge den ene af de 7?
Avatar billede j3ppah Novice
09. juni 2009 - 08:18 #6
Kan du ikke lige prøve at give et eksempel på 3 liniers output fra alle 3 table's?
Og så læige forklare spørgsmålet ordenligt igen.
for sådan som jeg har forstået det kan output fx. være.

1.  2.    3.

1    2    2
1    2    2
3    4    4
7    1    1
7    5    5

og det du så ænsker at få ud er.

1    2    2
3    4    4
7    1    1

???

Men kan næste regne ud dette ikke er korrekt forstået ?
Avatar billede joemoz Nybegynder
09. juni 2009 - 11:16 #7
@buzzz
Hmm...det ser kompliceret ud men jeg undersøger lige om det kan virke.

@arne
Det er faktisk ligemeget - bare evt. den første den finder

@j3ppah
Det er rigtigt forstået, bortset fra at tabel1+tabel2 hænger sammen så det principielt kunne være en tabel - dvs. der kan ikke være flere forskellige værdier i tabel2 til en given værdi fra tabel1. Så hvis du i dit eksempel ændrer linjen 7 5 5 til 7 1 5 er det korrekt.
Avatar billede j3ppah Novice
09. juni 2009 - 11:28 #8
Tror desvære stadig ikke jeg er helt med. :P...

Kunne du ikke lige tage at lave et setup som jeg gjorde i det sidste svar.

og så vise hvad du har, og hvad du vil have.
Avatar billede joemoz Nybegynder
09. juni 2009 - 12:52 #9
Jo:

Hvis resultatet af min query som udgangspunkt er sådan:

Tabel1.  Tabel2.    Tabel3.

A        KAT        123
A        KAT        432
C        HUND      483
G        ÆSEL      958
G        ÆSEL      534

Vil jeg gerne have at den kun tager én linje per tabel1/tabel2-værdi med - dvs.

Tabel1.  Tabel2.    Tabel3.

A        KAT        123
C        HUND      483
G        ÆSEL      958


Hvilken linje den tager med er ikke afgørende.
Avatar billede j3ppah Novice
09. juni 2009 - 13:19 #10
Hvis tal 3 er lige gyldig, hvorfor bruger du så ikke.

SELECT DISTINCT #Table1#, #Table2#
FROM #DATABASE#


:D... burde da absolut være den nemmeste løsning..

så får du alle for skellige variationer af tabel1 - tabel2
Der er i databasen..

Hvis du vil have lidt overblik, så

SELECT DISTINCT Tabel1, Tabel2
FROM Databasen
ORDER BY Tabel1



altså, hvis 3'eren er lige gyldig er det i hvertfald den nemmeste løsning
Avatar billede joemoz Nybegynder
09. juni 2009 - 13:36 #11
Den er ikke ligegyldig - én tabel3-værdi skal være med, det er bare ikke afgørende hvilken af dem.
Avatar billede joemoz Nybegynder
09. juni 2009 - 13:40 #12
Altså dermed menes selvfølgelig en tabel3 værdi der korresponderer (via key1) med tabel1/tabel2-værdierne - ikke en hvilken som helst random tabel3-værdi naturligvis.
Avatar billede Syska Mester
09. juni 2009 - 21:48 #13
Så tror jeg du skal over i min løsning ... jeg kan ikke komme på andre.

Da det ikke er muligt at lave et "join på first match af alle værdier" for hver unik værdi i en table over på en anden.

Derfor skal du først via en logik have sorteret det ud du vil have ... det kan du gøre med min logik længere oppe ... tager MAX(id) og gruppere på den værdi du joiner over på ... på den måde får du kun seneste row fra din 3 table.

// ouT
Avatar billede joemoz Nybegynder
10. juni 2009 - 10:00 #14
@buzzzz
Jeg kan godt se idéen - som jeg forstår det vil du generere en ny tabel hvor der kun er en tabel3-linje pr ID-værdi, men når jeg forsøger siger den "No column was specified for column 1 of 'dt1'."

Mangler jeg mon noget?
Avatar billede Syska Mester
10. juni 2009 - 13:27 #15
ups ... fordi den MAX(ID) ikke har fået angivet et navn ...

( SELECT MAX(ID) AS ID FROM table3 GROUP BY key1)

Her sætter vi navnet af den aggregate funktion til ID igen ... eller er den navneløs ...

// ouT
Avatar billede joemoz Nybegynder
10. juni 2009 - 13:45 #16
Tak - jeg har faktisk fået det til at virke i mellemtiden - der var lidt flere komplikationer bl.a. fordi der jo også skulle joines en tredje tabel og fordi jeg i den indre select funktion jo også var nødt til at inkludere key1 (ikke?) + en betingelse. Men metoden virkede så det var super, mange tak for det, smid endelig et svar.
Avatar billede Syska Mester
11. juni 2009 - 07:57 #17
svar.

Smid endelig dit resultat af din query her.

Jeg har brugt overstående metode til at trække sidste post ud fra en forum table ... overstående er ikke super performance venlig og nu smider jeg mit ID til thread table for hurtigere at kunne joine dem.

Men det er meningen at den midlertidige table skal bruges til at joine på de rigtige data ... da der foreksemple kunne være forskellige titeler på alle rows i table3 og man kun ville have 1 ... så joiner med den table over på table3 igen ... og kan på den måde få det ud.

// ouT
Avatar billede joemoz Nybegynder
11. juni 2009 - 10:08 #18
Ja det endte med

select tabel1.vaerdi1, tabel2.vaerdi2, dt1.v3 from tabel1 inner join (select key1 as noegle, max(vaerdi3) as v3 from tabel3 where felt2 = 'ABC' group by key1) as dt1 on tabel1.key1=dt1.noegle join tabel2 on tabel1.key1=tabel2.key1

For nu at blive i det eksempel jeg satte op.

Jeg kan vist ikke give dig point hvis ikke du sætter et svar ind?
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

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