Juiste syntax van GROUP BY icm de aggregate functies
Ik ben zelf een forum aan het schrijven en ik loop nu al tegen het eerste probleem, ik wil in een query alle categorieën selecteren en ook het aantal topics in die categorie.
Dit is de query die ik nu gebruik:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
$sFora = " SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c,
topics AS t
WHERE
t.t_id = c.c_id
;";
?>
$sFora = " SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c,
topics AS t
WHERE
t.t_id = c.c_id
;";
?>
De foutmelding die ik krijg:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
Error!
Fout: SQL-fout
Query: SELECT c.c_id, c.naam, COUNT(t.t_id) AS aantaltopics FROM cats AS c, topics AS t WHERE t.t_id = c.c_id ;
Errornummer: 1140
Foutmelding: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
Fout: SQL-fout
Query: SELECT c.c_id, c.naam, COUNT(t.t_id) AS aantaltopics FROM cats AS c, topics AS t WHERE t.t_id = c.c_id ;
Errornummer: 1140
Foutmelding: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
Ik begrijp hieruit dat ik iets met het GROUP BY element moet doen, maar daar begrijp ik niet heel erg veel van, ik heb hier een tutorial over GROUP BY gelezen maar ik snap het nog steeds niet echt.
Heeft iemand voor mij een werkende oplossing
Groetjes
Freek
Gewijzigd op 01/01/1970 01:00:00 door Citroen Anoniem Graag
De kolommen die niet in een functie als COUNT, MAX, MIN, AVG of ... voor komen, moeten in het GROUP BY gedeelte van de query voorkomen.
Gewijzigd op 01/01/1970 01:00:00 door Citroen Anoniem Graag
Bump
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$sFora = " SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c,
topics AS t
WHERE
t.t_id = c.c_id
GROUP BY
t.t_id
;";
?>
$sFora = " SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c,
topics AS t
WHERE
t.t_id = c.c_id
GROUP BY
t.t_id
;";
?>
En waarom, omdat je nu 2 tabellen vergelijkt moet je aangeven op welke kolom het tellen moet worden gegroepeerd.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$sFora = " SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c,
topics AS t
WHERE
t.t_id = c.c_id
GROUP BY
c.c_id,
c.naam
;";
?>
$sFora = " SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c,
topics AS t
WHERE
t.t_id = c.c_id
GROUP BY
c.c_id,
c.naam
;";
?>
Grouperen op alles wat je opvraagt
Klaasjan Boven schreef op 22.01.2007 18:43:
Grouperen op alles wat je opvraagt
Kan je uitleggen waarom? 1 id heeft ook maar 1 naam, dus dat is in dit geval niet nodig, alleen het Id moet voldoende zijn.
Ik krijg een resultaat van 0 dus er wordt niets gevonden.
Geen foutmelding of waarschuwing omdat de query niet fout is.
Robert schreef op 22.01.2007 18:56:
Kan je uitleggen waarom? 1 id heeft ook maar 1 naam, dus dat is in dit geval niet nodig, alleen het Id moet voldoende zijn.
Klaasjan Boven schreef op 22.01.2007 18:43:
Grouperen op alles wat je opvraagt
Kan je uitleggen waarom? 1 id heeft ook maar 1 naam, dus dat is in dit geval niet nodig, alleen het Id moet voldoende zijn.
Ik ga dat nog eens goed uitzoeken Robert volgens mij hebben we deze discussie al eens eerder gehad.
Ik werk ( op mijn werk) wel eens met SQL+ en Oracle en ik weet zeker dat je daarmee moet groeperen op alles wat in de SELECT staat behalve datgene wat je met de agregate?? functie, in dit geval COUNT() opvraagd
Edit:
wat zeggen de sql gurus alhier ervan. Ik verwacht minstens een recatie van Jan, Frank, Blanche, Willem vp en ik vergeet er vast nog wel een paar
Edit:
2 Ik zie nu nt dat Boaz btw ook zegt dat je moet groeperen op alles wat niet in de COUNT() voorkomt. Volgens mij gaat mysql er alleen niet goed mee om
Gewijzigd op 01/01/1970 01:00:00 door Klaasjan Boven
Echter MySQL maakt hier een uitzondering op. Je kunt met MySQL wel 'non-aggregated' kolommen opnemen die je niet in je GROUP BY clause hebt staan. Zie ook deze paragraaf uit de mysql handleiding.
ps. Wees er echter wel zeker van dat deze kolommen daadwerkelijk overbodige (redundante) informatie bevatten. Een voorbeeld is als een id maar gekoppeld kan zijn aan 1 naam en deze naam ook alleen maar gekoppeld kan zijn aan dat ene id. Dat is namelijk de enige mogelijkheid waarin je zeker weet dat de juiste naam ook bij het juiste id vermeld wordt.
Gewijzigd op 01/01/1970 01:00:00 door Joren de Wit
even weer terug naar mijn probleem, wat ik nog weet van GROUP BY is dat het samen gaat met HAVING en dat HAVING ongeveer gelijk is aan WHERE heeft het er misschien iets mee te maken dat in mijn huidige niet werkende query WHERE i.p.v having voorkomt?
Zoals ik het nu zie koppel je het id van een topic uit de tabel topics aan het id van een categorie uit de tabel cats. Dit is niet juist.
Je zult de kolom met het id van een categorie uit de tabel cats moeten koppelen aan een kolom in de tabel topics die aangeeft tot welke categorie een topic behoort. Oftwel de foreign key uit de topics tabel die slaat op de categorie tabel.
ps. HAVING ga je hoogstwaarschijnlijk niet nodig hebben in je query.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$sFora = " SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c,
topics AS t
WHERE
t.t_id = c.c_id
GROUP BY
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
";
?>
$sFora = " SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c,
topics AS t
WHERE
t.t_id = c.c_id
GROUP BY
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
";
?>
en zo?
Edit:
@ Blanche ik snap niet waarom dat in MYSQL nou weer anders moet zijn. Het wordt iig niet makkelijker van
Gewijzigd op 01/01/1970 01:00:00 door Klaasjan Boven
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
-- phpMyAdmin SQL Dump
-- version 2.8.2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generatie Tijd: 22 Jan 2007 om 20:11
-- Server versie: 5.0.27
-- PHP Versie: 5.1.4
--
-- Database: `forum`
--
[edit]
Heb de namen van phphulp.nl overgenomen om te testen om het forum te maken, wordt nog anders ga het natuurlijk niet namaken, als het af is is het de bedoeling dat als je de setup draait zelf een forum kan 'maken'
[/edit]
-- --------------------------------------------------------
--
-- Tabel structuur voor tabel `cats`
--
CREATE TABLE `cats` (
`c_id` smallint(3) NOT NULL auto_increment,
`naam` varchar(30) NOT NULL,
PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
--
-- Gegevens worden uitgevoerd voor tabel `cats`
--
INSERT INTO `cats` VALUES (1, 'PHP');
INSERT INTO `cats` VALUES (2, 'SQL');
INSERT INTO `cats` VALUES (3, 'OOP');
INSERT INTO `cats` VALUES (4, 'Koffiehoek');
-- --------------------------------------------------------
--
-- Tabel structuur voor tabel `members`
--
CREATE TABLE `members` (
`m_id` mediumint(10) NOT NULL auto_increment,
`voornaam` varchar(50) NOT NULL,
`achternaam` varchar(50) NOT NULL,
`straatnaam` varchar(50) NOT NULL,
`huisnummer` varchar(6) NOT NULL,
`postcode` varchar(6) NOT NULL,
`land` smallint(1) NOT NULL default '0',
`geslacht` varchar(1) NOT NULL,
`geboortedatum` datetime NOT NULL,
`about` text NOT NULL,
`msn` varchar(50) NOT NULL default '0',
`website` varchar(30) NOT NULL default '0',
`email` varchar(50) NOT NULL,
`gebruikersnaam` varchar(20) NOT NULL,
`wachtwoord` varchar(32) NOT NULL,
`ip` varchar(20) NOT NULL,
`registreerdatum` datetime NOT NULL,
`laatstonline` datetime NOT NULL,
`posts` smallint(5) NOT NULL default '0',
`rank` smallint(1) NOT NULL default '0',
`geactiveerd` smallint(1) NOT NULL default '0',
`f_afbeelding` smallint(6) NOT NULL default '0',
`p_afbeelding` smallint(6) NOT NULL default '0',
PRIMARY KEY (`m_id`),
UNIQUE KEY `uniekemailgebruikersnaam` (`gebruikersnaam`,`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
--
-- Gegevens worden uitgevoerd voor tabel `members`
--
INSERT INTO `members` VALUES (1, 'Freek', 'Boutkan', 'Prinses Irenelaan', '52', '2341TT', 0, 'M', '1992-05-13 19:17:43', 'Hoi, ik ben een lid', '0', '0', '[email protected]', 'freeky', '147538da338b770b61e592afc92b1ee6', '192.168.1.33', '2007-01-17 19:19:00', '2007-01-17 19:19:00', 0, 0, 0, 0, 0);
-- --------------------------------------------------------
--
-- Tabel structuur voor tabel `topics`
--
CREATE TABLE `topics` (
`t_id` int(12) NOT NULL,
`m_id` mediumint(10) NOT NULL,
`c_id` smallint(3) NOT NULL,
`vraag` text NOT NULL,
PRIMARY KEY (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Gegevens worden uitgevoerd voor tabel `topics`
--
-- version 2.8.2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generatie Tijd: 22 Jan 2007 om 20:11
-- Server versie: 5.0.27
-- PHP Versie: 5.1.4
--
-- Database: `forum`
--
[edit]
Heb de namen van phphulp.nl overgenomen om te testen om het forum te maken, wordt nog anders ga het natuurlijk niet namaken, als het af is is het de bedoeling dat als je de setup draait zelf een forum kan 'maken'
[/edit]
-- --------------------------------------------------------
--
-- Tabel structuur voor tabel `cats`
--
CREATE TABLE `cats` (
`c_id` smallint(3) NOT NULL auto_increment,
`naam` varchar(30) NOT NULL,
PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
--
-- Gegevens worden uitgevoerd voor tabel `cats`
--
INSERT INTO `cats` VALUES (1, 'PHP');
INSERT INTO `cats` VALUES (2, 'SQL');
INSERT INTO `cats` VALUES (3, 'OOP');
INSERT INTO `cats` VALUES (4, 'Koffiehoek');
-- --------------------------------------------------------
--
-- Tabel structuur voor tabel `members`
--
CREATE TABLE `members` (
`m_id` mediumint(10) NOT NULL auto_increment,
`voornaam` varchar(50) NOT NULL,
`achternaam` varchar(50) NOT NULL,
`straatnaam` varchar(50) NOT NULL,
`huisnummer` varchar(6) NOT NULL,
`postcode` varchar(6) NOT NULL,
`land` smallint(1) NOT NULL default '0',
`geslacht` varchar(1) NOT NULL,
`geboortedatum` datetime NOT NULL,
`about` text NOT NULL,
`msn` varchar(50) NOT NULL default '0',
`website` varchar(30) NOT NULL default '0',
`email` varchar(50) NOT NULL,
`gebruikersnaam` varchar(20) NOT NULL,
`wachtwoord` varchar(32) NOT NULL,
`ip` varchar(20) NOT NULL,
`registreerdatum` datetime NOT NULL,
`laatstonline` datetime NOT NULL,
`posts` smallint(5) NOT NULL default '0',
`rank` smallint(1) NOT NULL default '0',
`geactiveerd` smallint(1) NOT NULL default '0',
`f_afbeelding` smallint(6) NOT NULL default '0',
`p_afbeelding` smallint(6) NOT NULL default '0',
PRIMARY KEY (`m_id`),
UNIQUE KEY `uniekemailgebruikersnaam` (`gebruikersnaam`,`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
--
-- Gegevens worden uitgevoerd voor tabel `members`
--
INSERT INTO `members` VALUES (1, 'Freek', 'Boutkan', 'Prinses Irenelaan', '52', '2341TT', 0, 'M', '1992-05-13 19:17:43', 'Hoi, ik ben een lid', '0', '0', '[email protected]', 'freeky', '147538da338b770b61e592afc92b1ee6', '192.168.1.33', '2007-01-17 19:19:00', '2007-01-17 19:19:00', 0, 0, 0, 0, 0);
-- --------------------------------------------------------
--
-- Tabel structuur voor tabel `topics`
--
CREATE TABLE `topics` (
`t_id` int(12) NOT NULL,
`m_id` mediumint(10) NOT NULL,
`c_id` smallint(3) NOT NULL,
`vraag` text NOT NULL,
PRIMARY KEY (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Gegevens worden uitgevoerd voor tabel `topics`
--
Gewijzigd op 01/01/1970 01:00:00 door Citroen Anoniem Graag
SELECT c.c_id, COUNT(t.t_id) AS aantaltopics
FROM cats AS c, topics AS t
WHERE t.t_id = c.c_id
en
SELECT c.c_id, c.naam,
FROM cats AS c, topics AS t
WHERE t.t_id = c.c_id
@Willem: Deze error krijg ik, we zijn weer precies even ver als waar we begonnen *zucht*
Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
Edit:
De namen die in de database staan zijn overgenomen van PHP hulp om gewoon iets te inserte, ik ga het niet namaken of zo het moet een forum worden waar de admin cats can toevoegen en verwijderen maar dat komt later
De namen die in de database staan zijn overgenomen van PHP hulp om gewoon iets te inserte, ik ga het niet namaken of zo het moet een forum worden waar de admin cats can toevoegen en verwijderen maar dat komt later
Gewijzigd op 01/01/1970 01:00:00 door Citroen Anoniem Graag
SELECT c.c_id, COUNT(t.t_id) AS aantaltopics
FROM cats AS c, topics AS t
WHERE t.t_id = c.c_id
GROUP BY t.t_id
Ik krijg weer geen resultaten :S
Klaasjan Boven schreef op 22.01.2007 20:11:
ik snap niet waarom dat in MYSQL nou weer anders moet zijn. Het wordt iig niet makkelijker van
Het wordt er juist wel makkelijker van. Het is een uitbreiding die de normale werking van GROUP BY niet verandert.
Quote:
ik weet zeker dat je daarmee moet groeperen op alles wat in de SELECT staat behalve datgene wat je met de agregate?? functie, in dit geval COUNT() opvraagd
Wat je hier zegt, klopt in ieder geval niet. Je mag ook rustig op slechts 1 veld groeperen; de enige voorwaarde is dat dat veld ook voorkomt in de SELECT. Die voorwaarde is er by MySQL niet. Je mag dus rustig iets doen als:
SELECT COUNT(id)
FROM tabel
GROUP BY name
En dit mag niet in "puur" SQL, daar moet je het veld name toevoegen aan je select.
Freek schreef op 22.01.2007 20:28:
Toch es even naar je tabel-definities gekeken. Ik vermoed dat je WHERE-clause verkeerd is. Die zou moeten zijn:Ik krijg weer geen resultaten :S
WHERE t.c_id = c.c_id
Edit: En uiteraard moet je dus ook COUNT(t.c_id) gebruiken.
Gewijzigd op 01/01/1970 01:00:00 door Willem vp
Volgens mij is het eerder zo:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c
LEFT JOIN
topics AS t
ON
c.c_id = t.c_id
GROUP BY
c.c_id,
c.naam
c.c_id,
c.naam,
COUNT(t.t_id) AS aantaltopics
FROM
cats AS c
LEFT JOIN
topics AS t
ON
c.c_id = t.c_id
GROUP BY
c.c_id,
c.naam
ps.
Quote:
Maar als er meerdere kolommen in je SELECT voorkomen zul je daar in standaard SQL ook op moeten groeperen. Dit hoeft in MySQL niet, en dat is een uitzondering. En volgens mij mag je in standaard SQL ook prima groeperen op een kolom die niet in je SELECT query voor komt!Wat je hier zegt, klopt in ieder geval niet. Je mag ook rustig op slechts 1 veld groeperen; de enige voorwaarde is dat dat veld ook voorkomt in de SELECT. Die voorwaarde is er by MySQL niet.
Gewijzigd op 01/01/1970 01:00:00 door Joren de Wit