Count Query

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

D B

D B

23/09/2013 19:09:38
Quote Anchor link
Hallo,

Ik heb het volgende:

Een tabel Goals met daarin alle goals die gevallen zijn zoals onderstaand:
id-wedstrijd_id-leden_id-minuut
1-2-29-3
2-2-55-5
3-2-55-10

Nu wil ik alle goals van 1 persoon bij elkaar optellen en dan wil ik die goals ORDER BY maken.

Via de leden_id haal ik op in welk team het lid speelt, zodat ik daar later ook nog wat mee kan.

Maar als ik onderstaande query gebruik geeft hij aan dat bijvoorbeeld lid 29 4x gescoord heeft, dit komt -volgens mij- omdat het leden_id meerdere keren in Teamindeling voor komt, omdat deze persoon namelijk in meerdere teams speelt/coacht.

Ik heb het volgende geprobeerd:
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
<?
SELECT
    l.voornaam,
    l.achternaam,
    COUNT(g.leden_id),
FROM
    Goals as g
LEFT JOIN
    Leden AS l
ON
    (g.leden_id = l.id)
LEFT JOIN
    Teamindeling AS t
ON
    (g.leden_id = t.leden_id) AND t.seizoen = '2013/2014'
WHERE
    g.leden_id != '0'
GROUP BY
    g.leden_id
?>


Hopelijk kunnen jullie me wat verder helpen.
 
PHP hulp

PHP hulp

17/11/2024 11:37:34
 
Erwin H

Erwin H

23/09/2013 21:50:24
Quote Anchor link
Selecteer het aantal doelpunten eerst in een subquery en join daar de rest bij:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
SELECT l.voornaam, l.achternaam, c.num
FROM (
  SELECT leden_id, COUNT(*) AS num
  FROM goals
  GROUP BY leden_id
) c
LEFT JOIN Leden l ON c.leden_id = l.leden_id
ORDER BY c.num DESC

Wat me nu alleen niet helemaal duidelijk is, is waarom je de teamindeling er nog bij joint. Die gebruik je verder helemaal niet.
Gewijzigd op 23/09/2013 21:50:42 door Erwin H
 
D B

D B

23/09/2013 21:57:57
Quote Anchor link
De teamindeling ga ik nog gebruiken om op te halen in welk team dat ze spelen, en dan om te sorteren op senioren en junioren teams. Ik ga nu kijken of je query werkt.

Bedankt voor het meedenken iniedergeval!
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

23/09/2013 22:02:40
Quote Anchor link
Je hebt nu precies de verkeerde volgorde.
Je gaat leden koppelen aan goals ipv van de goals aan leden.

Met andere woorden, je moet eerst de leden ophalen uit de leden tabel, daarna doe je een INNER JOIN op de team indeling, en dan pas ga je met een left join de goals erbij betrekken.

En natuurlijk moet je geen GROUP BY doen op:
a) een kolom die niet in de select list staat
b) een kolom die een geen waarde kan bevatten (indien je het in de juiste volgorde zet)

En helemaal officieel horen alle niet aggegrate kolommen in de select list ook in de group by te staan.

Tipje (ff reclame gheghe)
 
D B

D B

23/09/2013 22:08:20
Quote Anchor link
Nu probeer ik hem verder uit te werken, maar dat pikt hij dus niet :)

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
<?
SELECT
    l.voornaam,
    l.achternaam,
    c.num,
    l.id
FROM (
    SELECT
        leden_id,
        COUNT(*) AS num
    FROM
        Goals
    GROUP BY
        leden_id
)
AS

    c
LEFT JOIN
    Leden AS l                //Voor voor en achternaam
ON
    (c.leden_id = l.id)
LEFT JOIN
    Teams AS teams            //Om te kijken voor welk team het is
ON
    (g.wie = teams.team) AND teams.seizoen = '2013/2014'
WHERE
    g.leden_id != '0'
AND
    teams.leeftijd = 'Senioren'
ORDER BY
    c.num DESC
?>
Gewijzigd op 23/09/2013 22:09:02 door D B
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

23/09/2013 22:17:33
Quote Anchor link
Zie mijn vorige reactie.
 
D B

D B

24/09/2013 10:35:02
Quote Anchor link
Hallo,

Ik heb nu het volgende:
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
<?
SELECT
    l.voornaam,
    l.achternaam,
    teams.team,
    count(g.leden_id)
FROM
    Leden AS l
INNER JOIN
    Teamindeling AS t
ON
    (l.id = t.leden_id) AND t.seizoen = '2013/2014'
LEFT JOIN
    Teams AS teams
ON
    (t.team_id = teams.id)
LEFT JOIN
    Goals AS g
ON
    (l.id = g.leden_id) AND g.seizoen = '2013/2014'
WHERE
    l.id = '29' //even om van 1 speler te testen
AND
    t.taak = 'Speler'
?>


Maar nu heb ik dus uit meerdere teams in teamindeling, maar dat telt hij met de count ook bij elkaar op???
Terwijl ik natuurlijk alleen de goals wil tellen. Moet dit dan via een subquery ofzo?
Gewijzigd op 24/09/2013 10:39:47 door D B
 
Erwin H

Erwin H

24/09/2013 10:41:54
Quote Anchor link
Zolang je de doelpunten telt op een query waarin je al de teams hebt gejoined blijf je dat probleem houden. Wat mij betreft is de tip van Ger dan ook ofwel verkeerd (sorry Ger), ofwel niet voldoende geformuleerd. Het tellen van de doelpunten zal je apart moeten doen van het joinen van alle andere tabellen, anders blijf je verkeerd gaan. Dus in een subquery en of je die als hoofdtabel neemt, of dat je er later via een join bij zet is dan om het even.
Let overigens wel op dat als een speler in meerdere teams voorkomt, hij dus ook meerdere records krijgt in je uiteindelijke resultaat. Dit kan je alleen voorkomen als je een GROUP_CONCAT gebruikt: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
 
D B

D B

24/09/2013 12:29:52
Quote Anchor link
Ok.

De goals staan gewoon per id in tabel Goals. Hoe zou ik deze dan (in mijn left join) met een subquery op kunnen laten tellen en meenemen in mijn 'hoofd'query?
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

24/09/2013 12:53:45
Quote Anchor link
@Erwin
Mijn tip c.q. opmerking ging over de volgorde, en die is bij een outer join cruciaal voor het uiteindelijke resultaat.

@DB
Als je dus per lid de goals wilt tellen (maar ook voor degenen die niet gescoord hebben), selecteer je vanuit de leden tabel. Maar omdat een lid bij meerdere teams kan spelen zal je met een subquery ervoor moeten zorgen dat je een view krijgt met per lid 1 record, daarna kan je gewoon de goals tabel left joinen:
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
SELECT
    lid.voornaam,
    lid.achternaam,
    lid.teams,
    COUNT(g.leden_id) aantal_goals
FROM
    (SELECT
        l.id,
        l.voornaam,
        l.achternaam,
        GROUP_CONCAT(t.team) teams
    FROM
        leden l
    JOIN
        teamindeling ti
        ON l.id = ti.leden_id
    JOIN
        teams t
        ON t.id = ti.team_id
    WHERE ti.taak = 'Speler' AND ti.seizoen = '2013/2014'
    GROUP BY l.id, l.voornaam, l.achternaam
    ) lid
LEFT JOIN goals g
ON
    lid.id = g.leden_id AND g.seizoen = '2013/2014'
GROUP BY
lid.voornaam, lid.achternaam, lid.teams

Edit:

Wat sleur-pleur foutjes eruit gehaald.
Gewijzigd op 24/09/2013 12:58:44 door Ger van Steenderen
 
Erwin H

Erwin H

24/09/2013 13:04:55
Quote Anchor link
@Ger, dat bedoelde ik dus met dat je opmerking niet voldoende was. Omdat hij spelers heeft met links naar verschillende teams krijg je die spelers meerdere keren en als je daar simpelweg de goals aan gaat hangen dan gaat het fout. In dit complete voorbeeld heb je dat opgelost door de GROUP_CONCAT. In je eerdere opmerking stond daar niets over.
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

24/09/2013 13:32:27
Quote Anchor link
Met hindsight was ie inderdaad incompleet. Ik had toen de gedachte: een speler speelt bij één team en/of is coach bij één of meer andere teams.

Alleen jij stelde dat het niet uit maakt waar de subquery staat, en dat is onjuist. Als je de volgorde in het voorbeeld omdraait krijg je een ander resultaat.
Gewijzigd op 24/09/2013 13:33:24 door Ger van Steenderen
 
Erwin H

Erwin H

24/09/2013 14:10:38
Quote Anchor link
Dat ligt eraan wat je wil hebben inderdaad. Als je ook de spelers wilt hebben in het overzicht die 0 keer hebben gescoord dan krijg je die niet als je eerst de goals telt.
 
D B

D B

04/10/2013 08:17:15
Quote Anchor link
Ok, nu ben ik hier wat verder op in aan het gaan, en wil ik mijn scores apart per team. Ik krijg dit goed voor elkaar, alleen zit ik nog met de mensen die niet gescoord hebben, deze laat hij nu dus niet zien.

Dit heb ik nu: (ik dacht met een COALESCE te kunnen werken, maar dit lijkt niet goed)

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
41
42
43
44
45
46
47
48
49
50
51
52
53
<?

SELECT
        lid.voornaam,
        lid.achternaam,
        lid.team,
        lid.id,
        COALESCE(COUNT(g.leden_id), 0) AS aantal_goals
    FROM
            (SELECT
            l.id,
            l.voornaam,
            l.achternaam,
            t.team
        FROM
            Leden AS l
        JOIN
            Teamindeling AS ti
        ON
            (l.id = ti.leden_id)
        JOIN
            Teams AS t
        ON
            (t.id = ti.team_id)
        WHERE
            ti.taak = 'Speler'
        AND
            ti.seizoen = '2013/2014'
        AND
            t.team = 'ZSC 5'
        GROUP BY
            l.id,
            l.voornaam,
            l.achternaam
            ) AS lid
    LEFT JOIN
        Goals AS g
    ON
            (lid.id = g.leden_id) AND g.seizoen = '2013/2014' AND g.wie LIKE 'ZSC%'
    LEFT JOIN
        Wedstrijden AS w
    ON
            (g.wedstrijd_id = w.id)
    WHERE
        w.soort = 'Competitie'
    GROUP BY
        lid.voornaam,
        lid.achternaam,
        lid.team
    ORDER BY
        aantal_goals DESC

?>
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

04/10/2013 13:36:41
Quote Anchor link
Coalesce op count heeft geen zin, count geeft altijd wat terug (in tegenstelling tot de andere aggegrate functies).
Maar wat je niet goed doet is een WHERE op een kolom uit een tabel via een left join. Daarmee vervalt het effect van de left join want je filtert de rijen waarvan w.soort NULL zijn eruit.

Oplossing is een geneste join of een subquery.

Geneste join:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
.....
LEFT JOIN
    (goals g
    INNER JOIN
        wedstrijden w
        ON (g.wedstrijd_id = w.id) AND (w.soort = 'Competitie')
    )
    ON
    (lid.id = g.leden_id) AND g.seizoen = '2013/2014' AND g.wie LIKE 'ZSC%'


Subquery:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
LEFT JOIN
    (SELECT
        leden_id
    FROM goals
    JOIN wedstrijden w
        ON goals.wedstrijd_id = w.id
    WHERE
        g.seizoen = '2013/2014' AND g.wie LIKE 'ZSC%'
    AND w.soort = 'Competitie') g


Ook is de eerste subquery niet meer nodig, die was alleen nodig om te voorkomen dat leden die in meerdere teams spelen dubeel geselecteerd worden, maar nu je het per team doet is dat niet meer nodig.
 
D B

D B

05/10/2013 09:47:53
Quote Anchor link
Hier moet ik echt nog mee leren werken :)

Als ik die subquery in die left join gebruik, moet ik dan ook nog een ON hebben?

Ik heb nu dit: (krijg 1 speler te zien :))

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
41
42
<?
$query
= "
    SELECT
        l.voornaam,
        l.achternaam,
        COUNT(go.leden_id) aantal_goals
    FROM
        Leden AS l
    LEFT JOIN
        (SELECT
            leden_id
        FROM
            Goals AS g
        JOIN
            Wedstrijden AS w
        ON
            g.wedstrijd_id = w.id
        WHERE
            g.seizoen = '"
. $seizoen. "' AND g.wie LIKE 'ZSC%'
        AND
            w.soort = 'Competitie')
        AS go
    ON
        (l.id = go.leden_id)
    JOIN
        Teamindeling AS t
    ON
        (l.id = t.leden_id)
    JOIN
        Teams AS team
    ON
        (team.id = t.team_id)
    WHERE
        t.taak = 'Speler'
    AND
        t.seizoen = '"
. $seizoen. "'
    AND
        t.team_id = '"
. $teamid. "'
    ORDER BY
        aantal_goals DESC
"
;
?>
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

05/10/2013 11:03:10
Quote Anchor link
Ik was inderdaad de ON vergeten bij de subquery.

En jij bent de GROUP BY vergeten, zonder dat groepeer je de gehele recordset en krijg je dus maar één record
 



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.