Jag sitter med ett system som håller i orienteringstävlingar och ska göra en samling av klasser(H21, D21 osv) med mitt eget urval och min egen sortering. I dina SQL-satser så använder du tabellen/frågan "EventRaces" hur ser den ut, jag hittar inget exempel på den i din fråga. Hmm... jag hade visst strippat tabellerna lite för mycket. Hej igen, Det gav en del av svaret ialalfall, så de som är delade kommer med. Så här löste jag det hela:Joina sig själv, ibland...
Det är 4 tabeller som är inblandade 2 st generella och 2 st som är tävlingsspecifika (Man kan ha flera tävlingar i samma databas)
De 2 generella tabelelrna...
ClassCollectionClasses:
ClassCollectionId baseClassId ordered
4 21 2
4 24 3
4 27 4
4 43 5
4 46 6
4 49 7
4 52 8
BaseClasses:
classId name
----------- --------------
18 H35 LÅNG
21 H21 LÅNG
24 H20 LÅNG
27 H18 LÅNG
43 D35 LÅNG
46 D21 LÅNG
49 D20 LÅNG
52 D18 LÅNG
Min samling (ClassCollectionClasses) byger alltså på att jag gör ett val av basklasser.
Under tävlingen sedan till kommer två tabeller.
EventClasses:
eventClassId name classId dividedFrom
------------ -------------------------------------------------- ----------- -----------
18 H35 LÅNG 18 NULL
21 H21 LÅNG 21 NULL
24 H20 LÅNG 24 NULL
27 H18 LÅNG 27 NULL
43 D35 LÅNG 43 NULL
46 D21 LÅNG 46 NULL
49 D20 LÅNG 49 NULL
52 D18 LÅNG 52 NULL
(classId = BaseClasses.classId)
RaceClasses:
raceClassId eventClassId
----------- ------------
18 18
21 21
24 24
27 27
43 43
46 46
49 49
52 52
(Just nu är det en slump att raceClassId & eventClassId är lika)
Det jag nu vill göra är att få fram de raceClassId som är aktuella enligt den samling jag gjort. Det gör jag med följande SQL-sats:
<code>
SELECT raceClassId, EventClasses.name,
EventClasses.dividedFrom
FROM (((RaceClasses RIGHT JOIN
EventRaces ON
EventRaces.eventRaceId = RaceClasses.eventRaceId) LEFT
JOIN
EventClasses ON
EventClasses.eventClassId = RaceClasses.eventClassId) LEFT
JOIN
ClassCollectionClasses ON
ClassCollectionClasses.baseClassId = EventClasses.eventClassId)
WHERE ClassCollectionClasses.classCollectionId = 4
ORDER BY ClassCollectionClasses.ordered
</code>
Nu är det tyvärr så att ibland blir en klass för stor så att den måste delas i flera, då får EventClass följande utseende:
EventClasses:
eventClassId name classId dividedFrom
------------ -------------------------------------------------- ----------- -----------
18 H35 LÅNG 18 NULL
21 H21 LÅNG 21 NULL
78 H21 Lång 1 72 21
79 H21 Lång 2 73 21
24 H20 LÅNG 24 NULL
27 H18 LÅNG 27 NULL
43 D35 LÅNG 43 NULL
46 D21 LÅNG 46 NULL
49 D20 LÅNG 49 NULL
52 D18 LÅNG 52 NULL
RaceClasses ser då ut som följer:
RaceClasses:
raceClassId eventClassId
----------- ------------
18 18
21 21
24 24
27 27
43 43
46 46
49 49
52 52
78 78
79 79
Nu vill jag alltså komma åt de klasser som har fått ett värde i EventClasses.dividedFrom och här tar det stopp.
Jag gjorde ett försök enligt följande:
<code>
SELECT raceClassId, EventClasses.name,
EventClasses.dividedFrom
FROM (((RaceClasses RIGHT JOIN
EventRaces ON
EventRaces.eventRaceId = RaceClasses.eventRaceId) LEFT
JOIN
EventClasses ON
EventClasses.eventClassId = RaceClasses.eventClassId) LEFT
JOIN
ClassCollectionClasses ON
ClassCollectionClasses.baseClassId = EventClasses.eventClassId)
LEFT JOIN EventClasses as ec ON ec.dividedFrom = ClassCollectionClasses.baseClassId
WHERE ClassCollectionClasses.classCollectionId = 4
ORDER BY ClassCollectionClasses.ordered
</code>
Men då får jag ut den delade klassen flera gånger (alltså H21) istf för de nya klasserna.
Databasen är SQL-server, tabellstrukturen kan jag inte göra något åt i det här läget, samt att sorteringen är viktig.
Hoppas någon kan hjälpa mig!
/Per-ErikSv: Joina sig själv, ibland...
t ex "EventRaces.eventRaceId"Sv: Joina sig själv, ibland...
eventRaceId i det här fallet håller bara reda på vilken tävling som administreras så det blir ungefär så här:
EventRace:
eventRaceId name
-------------- -------
1 Tävling 1
2 Tävling 2
Då blir också RaceClasses lite annorlunda
RaceClasses:
raceClassId eventClassId eventRaceId
----------- ------------ ---------------
18 18 1
21 21 1
24 24 1
27 27 1
43 43 1
46 46 1
49 49 1
52 52 1
78 78 1
79 79 1
Nu tror jag att jag fått med allt...
/Per-ErikSv: Joina sig själv, ibland...
är inte 100-säker på att detta är det du vill ha men jag tror det är det här.
SELECT RaceClasses.raceClassId, EventClasses.name, EventClasses.dividedFrom FROM EventClasses INNER JOIN
RaceClasses ON EventClasses.eventClassId = RaceClasses.eventClassId INNER JOIN
ClassCollectionClasses ON EventClasses.dividedFrom = ClassCollectionClasses.baseClassId
GROUP BY RaceClasses.raceClassId, EventClasses.name, EventClasses.dividedFrom, ClassCollectionClasses.ClassCollectionId, ClassCollectionClasses.ordered
HAVING (ClassCollectionClasses.ClassCollectionId = 4)
ORDER BY ClassCollectionClasses.ordered
Hoppas det ger dig det du vill ha
//
JanneSv: Joina sig själv, ibland...
Men jag skulle vilja ha alla klasser med, även de som inte är delade.
Resultet ska bli nåt liknande detta (Jag har ändrat raceClassId för att det ska synas att det inte är samma som eventClassId)
raceClassId name
112 H35 LÅNG
113 H21 LÅNG
114 H21 Lång 1
115 H21 Lång 2
116 H20 LÅNG
117 H18 LÅNG
118 D35 LÅNG
119 D21 LÅNG
120 D20 LÅNG
121 D18 LÅNG
Jag tror mig klara av att få ut rätt klasser med hjälp av subselects, men då får jag dom inte i den ordning som jag vill, utan måste då skriva en extern sorteringsrutin.
/Per-ErikSv: Joina sig själv, ibland...
<code>
String query = "SELECT raceClassId FROM (RaceClasses LEFT JOIN EventClasses ON "
+ "EventClasses.eventClassId = RaceClasses.eventClassId) LEFT JOIN "
+ "ClassCollectionClasses ON (ClassCollectionClasses.baseClassId = EventClasses.classId OR "
+ "ClassCollectionClasses.baseClassId = EventClasses.dividedFrom) "
+ "WHERE (EventClasses.classId IN (SELECT baseClassId FROM ClassCollectionClasses "
+ "WHERE ClassCollectionClasses.classCollectionId = " + ccId.toString() +") AND "
+ "RaceClasses.eventRaceId = " + eventRaceId.toString() +" AND ClassCollectionClasses.classCollectionId=" + ccId.toString() +") OR "
+ "(EventClasses.dividedFrom IN (SELECT baseClassId FROM ClassCollectionClasses "
+ "WHERE ClassCollectionClasses.classCollectionId = " + ccId.toString() +") "
+ "AND RaceClasses.eventRaceId = " + eventRaceId.toString() +" AND ClassCollectionClasses.classCollectionId=" + ccId.toString() +") "
+ "Order BY ClassCollectionClasses.ordered, RaceClasses.raceClassId";
</code>
Om det finns en effektivare lösning så är jag intresserad av en kommentar.
/Per-Erik