Voorrang in Query

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

D B

D B

09/06/2013 21:07:02
Quote Anchor link
Hallo,

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)
PHP script in nieuw venster Selecteer het PHP script
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
<?
    $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
            "
;
?>
 
PHP hulp

PHP hulp

16/04/2024 21:16:10
 
Erwin H

Erwin H

09/06/2013 21:38:55
Quote Anchor link
Maar wil je dan dat alle taken alsnog worden geselecteerd, dus dat je en de trainer taak ziet en de speler taak? In dat geval zal je het gewoon moeten sorteren.

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.
 
D B

D B

09/06/2013 21:47:55
Quote Anchor link
Hoe zou ik dat dan in die group by moeten doen?

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?
 
Erwin H

Erwin H

09/06/2013 22:05:43
Quote Anchor link
Met een case of if statement zou het wel wat lastig worden, omdat die gegevens in verschillende rijen van je tabel staan.

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)
PHP script in nieuw venster Selecteer het PHP script
1
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...)

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
 
D B

D B

09/06/2013 22:18:46
Quote Anchor link
Hoe zou ik dat dan in die group by moeten doen?

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?
 
Jeroen Jansen

Jeroen Jansen

10/06/2013 08:39:58
Quote Anchor link
met een case een extra veld voor sortering gebruiken (niet getest):

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
    $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
            ";
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

10/06/2013 08:52:05
Quote Anchor link
Dat gaat niet met case, maar wel met een meerdere left joins op de teamindeling en dan gebruik van COALECSE:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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

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
 
D B

D B

10/06/2013 10:19:31
Quote Anchor link
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?
 
Erwin H

Erwin H

10/06/2013 10:30:02
Quote Anchor link
NEE!

Stel je hebt deze drie rijen uit je database:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
id | taak
---+-----------
1  | speler
1  | trainer
1  | assistent

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.
 
D B

D B

10/06/2013 10:31:36
Quote Anchor link
Wat doet de group dan precies?
 
Erwin H

Erwin H

10/06/2013 10:38:17
Quote Anchor link
Een GROUP BY gebruik je om aggregate waardes te splitsen over verschillende rijen. Als je bijvoorbeeld een COUNT(*) hebt in je select dan zal je maar 1 rij terugkrijgen uit je query met voor die count het totaal aantal rijen. Als je nu wil dat je niet het grote totaal krijgt, maar het totaal per persoon bijvoorbeeld, dan groepeer je de waardes per persoon:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
SELECT persoon, COUNT(*)
FROM orders
GROUP BY persoon

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.
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

10/06/2013 10:38:54
Quote Anchor link
Inderdaad Erwin, helemaal mee eens
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.
 
D B

D B

10/06/2013 17:28:40
Quote Anchor link
Ok, ik ga hier mee aan de gang.

Dankjulliewel!
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.