Voorrang in Query
Ik gebruik onderstaande query om wat gegevens op te halen. Nu staat er in mijn tabel Teamindeling waar een persoon voetbalt of waar hij training geeft of assistent is. Als ik nu via deze query een persoon selecteert pakt hij de goede persoon, maar als dat bijvoorbeeld een trainer en een voetballer is, zou ik willen dat hij eerst het team selecteert waarvan hij voetballer is, is dit mogelijk? Dus een bepaalde volgorde van selecteren? IF t.taak = Speler <-- 1 if t.taak = Coach <-- 2 if t.taak = Assistent <-- 3.
Begrijpen jullie me?
Bedankt voor de hulp alvast!
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?
$query= "
SELECT
l.id,
l.knvb,
l.voornaam,
l.achternaam,
t.team_id,
teams.team,
s.goals
FROM
Ip as i
LEFT JOIN
Leden as l
ON
(l.id = i.id)
LEFT JOIN
Teamindeling as t
ON
(l.id = t.leden_id)
LEFT JOIN
Teams as teams
ON
(t.team_id = teams.id)
LEFT JOIN
Statistieken as s
ON
(l.id = s.leden_id)
WHERE
i.ip = '". $_SERVER['REMOTE_ADDR']. "'
AND
i.id != ''
GROUP BY l.id
";
?>
$query= "
SELECT
l.id,
l.knvb,
l.voornaam,
l.achternaam,
t.team_id,
teams.team,
s.goals
FROM
Ip as i
LEFT JOIN
Leden as l
ON
(l.id = i.id)
LEFT JOIN
Teamindeling as t
ON
(l.id = t.leden_id)
LEFT JOIN
Teams as teams
ON
(t.team_id = teams.id)
LEFT JOIN
Statistieken as s
ON
(l.id = s.leden_id)
WHERE
i.ip = '". $_SERVER['REMOTE_ADDR']. "'
AND
i.id != ''
GROUP BY l.id
";
?>
Als je alleen de hoogste wilt hebben dan zal je via een subquery eerst alleen die taak moeten selecteren die je wilt, dus de 'hoogste' bijvoorbeeld en daaraan via joins de rest weer moeten selecteren.
Overigens gebruik je nu wel de GROUP BY verkeerd. Je hebt geen aggregate functie, dus je kan eigenlijk geen GROUP BY gebruiken. Daarnaast zal het ook fouten gaan opleveren. Als bijvoorbeeld een lid nu in 2 teams zit, krijg je er maar 1 te zien, maar het is niet gedefinieerd welke je te zien krijgt.
Ik hoef eigenlijk altijd maar te kijken of de persoon bestaat met als taak voetballer, zoniet dan of hij bestaat als trainer en als laatste als assistent. Ik dacht dat in 1 query te zetten met case ofzo maar dat gaat niet?
Wat ik zou proberen is ervoor te zorgen dat ik die taken kan sorten op taak zodat speler boven trainer en die weer boven assistent komt. Eventueel kan je dat doen via een virtuele kolom. Vervolgens selecteer je alleen de hoogste taak (met MAX of MIN) en daar join je de rest gewoon aan.
Als idee:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
SELECT l.id, t.taak
FROM (
SELECT leden_id, MAX(taak)
FROM Teamindeling
GROUP BY leden_id
) t
LEFT JOIN Leden l ON l.id = t.leden_id;
(en de rest van je query, even geen zin om alles erbij te voegen...)
FROM (
SELECT leden_id, MAX(taak)
FROM Teamindeling
GROUP BY leden_id
) t
LEFT JOIN Leden l ON l.id = t.leden_id;
(en de rest van je query, even geen zin om alles erbij te voegen...)
Enige wat ik niet weet is of je de waardes in taak zo kan sorteren, daar zul je dus wel voor moeten zorgen.
Gewijzigd op 09/06/2013 22:06:09 door Erwin H
Ik hoef eigenlijk altijd maar te kijken of de persoon bestaat met als taak voetballer, zoniet dan of hij bestaat als trainer en als laatste als assistent. Ik dacht dat in 1 query te zetten met case ofzo maar dat gaat niet?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$query= "
SELECT
l.id,
l.knvb,
l.voornaam,
l.achternaam,
t.team_id,
teams.team,
s.goals,
case t.taak
when 'speler' then 1
when 'coach' then 2
when 'assistent' then 3
else 99
end as sortering
FROM
Ip as i
LEFT JOIN
Leden as l
ON
(l.id = i.id)
LEFT JOIN
Teamindeling as t
ON
(l.id = t.leden_id)
LEFT JOIN
Teams as teams
ON
(t.team_id = teams.id)
LEFT JOIN
Statistieken as s
ON
(l.id = s.leden_id)
WHERE
i.ip = '". $_SERVER['REMOTE_ADDR']. "'
AND
i.id != ''
GROUP BY l.id
order by sortering
";
SELECT
l.id,
l.knvb,
l.voornaam,
l.achternaam,
t.team_id,
teams.team,
s.goals,
case t.taak
when 'speler' then 1
when 'coach' then 2
when 'assistent' then 3
else 99
end as sortering
FROM
Ip as i
LEFT JOIN
Leden as l
ON
(l.id = i.id)
LEFT JOIN
Teamindeling as t
ON
(l.id = t.leden_id)
LEFT JOIN
Teams as teams
ON
(t.team_id = teams.id)
LEFT JOIN
Statistieken as s
ON
(l.id = s.leden_id)
WHERE
i.ip = '". $_SERVER['REMOTE_ADDR']. "'
AND
i.id != ''
GROUP BY l.id
order by sortering
";
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SELECT
l.id,
l.naam,
COALESCE(v.team_id, t.team_id, a.team_id) team_id,
COALESCE(v.taak, t.taak, a.taak) taak
FROM
leden l
LEFT JOIN
teamindeling v
ON l.id = v.lid_id AND v.taak = 1
LEFT JOIN
teamindeling t
ON l.id = t.lid_id AND t.taak = 2
LEFT JOIN
teamindeling a
ON l.id = a.lid_id AND a.taak = 3
WHERE
COALESCE(v.taak, t.taak, a.taak) IS NOT NULL
l.id,
l.naam,
COALESCE(v.team_id, t.team_id, a.team_id) team_id,
COALESCE(v.taak, t.taak, a.taak) taak
FROM
leden l
LEFT JOIN
teamindeling v
ON l.id = v.lid_id AND v.taak = 1
LEFT JOIN
teamindeling t
ON l.id = t.lid_id AND t.taak = 2
LEFT JOIN
teamindeling a
ON l.id = a.lid_id AND a.taak = 3
WHERE
COALESCE(v.taak, t.taak, a.taak) IS NOT NULL
COALESCE levert het eerste NOT NULL argument op of NULL als alle argumenten NULL zijn.
Dit zet je dan als subquery in de FROM of als je dit vaker moet gebruiken maak je er een view van.
Gewijzigd op 10/06/2013 09:03:21 door Ger van Steenderen
Ik zit er zelf ook nog eens over te denken, maar als ik die 3 mogelijkheden heb, kan ik dan niet gewoon group by taak doen en dan order nu taak DESC? Dan zal ook Speler bovenaan staan denk ik?
Stel je hebt deze drie rijen uit je database:
Als je nu een GROUP BY doet op id, dan krijg je 1 rij terug, maar het is dan niet gedefinieerd welke waarde voor taak je krijgt. Er is geen regel voor de mysql engine die zegt welke waarde hij dan moet pakken.
Wat doet de group dan precies?
Nu krijg je per verschillende persoon het totaal. Zou je dit zonder GROUP BY doen krijg je dus het grote totaal, plus een waarde voor persoon, maar het is dan niet gedefinieerd welke persoon je krijgt.
Dat laatste geldt dus ook voor jouw idee. Je groepeert de resultaten op id, maar voor alle andere kolommen die je selecteert die geen aggregate kolommen zijn is het niet gedefinieerd welke waarde je krijgt. Daarom moet je nooit GROUP BY gebruiken als je daar niet alle niet-aggregate kolommen in hebt staan.
GROUP BY moet altijd in combinatie met een aggegrate functie.
Als nu een lid in de teamindeling als eerste is ingevoerd als trainer wordt dus het team_id van het team dat hij/zij traint gekozen.
Maar goed ik heb de oplossing al gegeven.
Dankjulliewel!