Avatar billede shaagerup Nybegynder
23. september 2005 - 15:58 Der er 10 kommentarer og
1 løsning

Join, sortering og listning

Jeg har et problem med at lave en SQL-sætning... Jeg har eksempelvis følgende tabeller:

TABEL: "indhold"

id | tal1 | tal2 | tal3
-----------------------
1  | 23  | 2    | 4
2  | 23  | 3    | 4
3  | 27  | 2    | 5
4  | 45  | 2    | 5
5  | 45  | 2    | 5
6  | 45  | 3    | 5
-------------------------

TABEL: "gruppering"

id | indholdid | gruppeid
-------------------------
1  | 5        | 1
2  | 6        | 1
3  | 1        | 2
4  | 3        | 2
5  | 2        | 3
6  | 4        | 3
-------------------------

Jeg vil nu have et output af grupperne, sorteret efter mindste tal1. Er der to forskellige grupper med samme tal1 tages den af de to med mindst tal2. Er der to forskellige grupper med ens tal2, tages den med mindste tal3. Er der stadig tvivl, går sorteringen pr. id.


OUTPUT (i dette tilfælde):

gruppeid
--------
2 (da tal1=23, tal2=2)
3 (da tal1=23, tal2=3)
1 (da tal1=45)
--------

Er dette noget der kan lade sig gøre med alm. SQL? (til Access-database fra ASP).
Avatar billede claesdamlund Nybegynder
23. september 2005 - 16:15 #1
Egentlig burde du have en GruppeID i din Indhold tabel fremfor en IndholdID i din Gruppe tabel men anyhow:

SELECT DISTINCT Gruppeid
FROM gruppering
INNER JOIN indhold
ON gruppering.indholdid = indhold.indhold
ORDER BY tal1 , tal2 , tal3

Har ikke testet, men tror det virker.
Avatar billede shaagerup Nybegynder
24. september 2005 - 11:19 #2
Ifg. min erfaring, kan du ikke sortere efter noget, som ikke er med i din DISTINCT. Således vil det kun kunne lade sig gøre at "ORDER BY Gruppeid" her.

Andre forslag?
Avatar billede kjulius Novice
24. september 2005 - 13:26 #3
Det var en hård nød at knække, men efter en del eksperimenter er jeg kommet frem til følgende:

SELECT g.gruppeid, i.tal1, i.tal2, i.tal3
FROM [select gruppeid, tal1, tal2, min(tal3) as t1_tal3 from gruppering g, indhold i where i.id=g.indholdid group by gruppeid, tal1, tal2]. AS tmp1, [select gruppeid, tal1, min(tal2) as t2_tal2 from gruppering g, indhold i where i.id=g.indholdid group by gruppeid, tal1]. AS tmp2, [select gruppeid, min(tal1) as t3_tal1  from gruppering g, indhold i where i.id=g.indholdid group by gruppeid]. AS tmp3, gruppering AS g, indhold AS i
WHERE i.id=g.indholdid
and g.gruppeid=tmp1.gruppeid and g.gruppeid=tmp2.gruppeid and g.gruppeid=tmp3.gruppeid
and i.tal1=tmp1.tal1 and i.tal1=tmp2.tal1 and i.tal1=tmp3.t3_tal1
and i.tal2=tmp1.tal2 and i.tal2=tmp2.t2_tal2
and i.tal3=tmp1.t1_tal3
ORDER BY i.tal1, i.tal2, i.tal3;

Den kører i min Access 2003...
Avatar billede shaagerup Nybegynder
24. september 2005 - 14:21 #4
Med mine data (som er en udvidet version af ovenstående eksempel) var det nødvendigt at skrive "SELECT DISTINCT g.gruppeid, i.tal1, i.tal2, i.tal3 ....", for at undgå linjer der fremkom flere gange.

Jeg har nu implementeret din SQL-sætning i min ASP-kode, og det virker fortrinligt! Hvis du lægger et svar, får du dine points :-).
Avatar billede kjulius Novice
24. september 2005 - 15:26 #5
Jamen det gør jeg da gerne.. :-)
Avatar billede claesdamlund Nybegynder
24. september 2005 - 19:57 #6
Selvfølgelig kan du bruge Distinct på felter du ikke medtager i en Order By - de to ting har INTET med hinanden at gøre, bortset fra at Distinct implicit er nødt til at lave en opsortering af data. Og i øvrigt vil jeg påstå at mit foreslag gør præcist det du vil...
Avatar billede kjulius Novice
24. september 2005 - 20:32 #7
-->: claesdamlund: Tja, bortset fra, at Access kom med en fejl, da jeg prøvede den :-)

ORDER BY-delsætningen (tal1) er i konflikt med DISTINCT.
Avatar billede claesdamlund Nybegynder
24. september 2005 - 23:18 #8
Jeg gir´ mig - mærkeligt...

I øvrigt kan den laves lidt enklere:

SELECT first(right([tal1] & [tal2] & [tal3] & [gruppeid],1)) AS Gruppe
FROM gruppering INNER JOIN Indhold ON gruppering.indholdid = Indhold.ID
GROUP BY Right([tal1] & [tal2] & [tal3] & [gruppeid],1)
ORDER BY first([tal1] & [tal2] & [tal3] & [gruppeid]);
Avatar billede kjulius Novice
25. september 2005 - 00:21 #9
Jo, med de givne data er det da rigtigt, men hvad hvis gruppeid eller et af de andre felter pludselig består af flere eller færre cifre. Så vil det give et forkert resultat.

Med al mulig respekt, så mener jeg, at min query er mere generelt anvendelig.
Avatar billede kjulius Novice
25. september 2005 - 01:44 #10
Men alligevel, med lidt tilretning, hvor alle numeriske værdier tildeles en fast strenglængde, med foranstillede nuller, bliver din query da mere generel:

SELECT first([gruppeid]) AS gruppe
FROM gruppering INNER JOIN Indhold ON gruppering.indholdid = Indhold.ID
GROUP BY [gruppeid]
ORDER BY min(right("0000000000" & cstr([tal1]), 10) & right("0000000000" & cstr([tal2]), 10) & right("0000000000" & cstr([tal3]), 10));

Den viser godt nok ikke de tal, som danner grundlag for valget af gruppe, men det var jo heller ikke et krav.

Om den holder helt i alle tilfælde, ved jeg ikke. Den baserer sig, så vidt jeg kan se på, at data bliver sorteret i henhold til ORDER BY instruktionen FØR gruppering, hvorefter FIRST instruktionen vil fange den rigtige gruppe.
Hvilket måske/måske ikke vil være tilfældet hver gang.
Avatar billede shaagerup Nybegynder
25. september 2005 - 14:46 #11
Er der nogen af jer, som har lyst til en måske endnu hårdere nød at knække, tjek http://www.eksperten.dk/spm/650793 :-).

kjulius: Tjekkede dit seneste udtag fra ASP, og jeg kunne ikke umiddelbart få det til at virke. Jeg kører videre med den anden - selvom den er lang, kører det hurtigt nok.
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
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

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