Hoi!

Ik ben nieuw hier, en ben bezig met een bericht systeem te maken. Alleen is het punt dat mijn query niet helemaal goed wordt uitgevoerd. Ik krijg namelijk alleen de eerste twee berichten te zien van mijn tabel, terwijl er meer inzit.

Dit is mijn query:

$query = " SELECT b.*, COUNT(r.reactie_id) aantal_reacties FROM bericht as b left join reactie as r on b.bericht_id = r.bericht_id GROUP BY r.bericht_id ORDER BY bericht_id desc";

Wat is er fout aan? Ik heb deze query wel een keer op een andere hosting kunnen draaien, waarbij ik wel alle berichten krijg te zien. Ligt het aan mijn database? Wie kan mij helpen a.u.b.

Gr,
Wendy
Even netjes uitschrijven:

SELECT 
  b.*, 
  COUNT(r.reactie_id) aantal_reacties 
FROM 
  bericht as b 
    left join reactie as r on b.bericht_id = r.bericht_id 
GROUP BY 
  r.bericht_id 
ORDER BY 
  bericht_id desc

En daar wordt al een hoop duidelijk, deze query kan gewoon niet. Helaas staat MySQL hem wel toe en verzint MySQL resultaten waarvan je nooit zeker zult weten of ze nu wel of niet goed zijn. De GROUP BY kan namelijk niet, deze wordt ook door MySQL in STRICT-mode afgekeurd.

Zie de tutorials hoe je wel GROUP BY moet gebruiken:
GROUP BY: Het juiste gebruik ervan

Tip: Stel MySQL in op STRICT-mode
Deze query kan inderdaad niet. Je kunt niet alles * selecteren als je ergens op groepeert, dan zou de database moeten gokken wat je wil zien. MySQL doet dat graag voor je, maar dat is belachelijk. MySQL is geen pokerspeler al denkt het van wel. Gokken is niet iets waar hij zich mee bezig zou mogen houden.
Umm, zie dit niet als thread hijacking, maar.. ik heb een soort gelijk probleem, dus dan hoeven we niet nóg een topic aan te maken.


SELECT v.vluchtnummer, p.achternaam, COUNT(p.achternaam) as Personen
FROM Vlucht v INNER JOIN Passagier p ON v.vluchtnummer = p.vlucht
WHERE v.vluchtnummer = 4
GROUP BY v.vluchtnummer, p.achternaam


Dit werkt, nu krijg ik 2 vluchten waarvan in eentje twee personen zitten omdat ze dezelfde achternaam hebben. Alleen ik wel elk persoon apart in een rij, maar als ik p.achternaam weghaal bij de GROUP BY dan gaat ie uiteraard zeuren dat ik hem niet in de SELECT kan gebruiken omdat ie niet in de GROUP BY zit.
Is het dan wel mogelijk wat ik wil?
Zodra je GROUP BY moet gebruiken, dan ga je eigenschappen opvragen die voor de héle groep gelden. In het geval van Gerben krijg je dus dat de hele groep dezelfde achternaam moet hebben.

Ga je eerst afvragen welke gegevens je wilt opvragen, wat nu precies de vraag is. Pas daarna ga je de query opstellen.

Edit: Of zelfs queries, lang niet alle problemen zijn 1 vraag (dus query) te beantwoorden.
Ik wil alle passagiers van vlucht 4. Dit zijn er drie.

Tabel passagiers

/* Maak een table genaamd Passagier */
CREATE TABLE Passagier (
passagiernummer	INTEGER		NOT NULL,
Vlucht		INTEGER		NOT NULL,
Balie		INTEGER,
achternaam	CHAR(255)	NOT NULL,
geslacht	CHAR(1),
stoel		CHAR(3),
tijdstip	DATE,
PRIMARY KEY  (passagiernummer),
FOREIGN KEY (Vlucht) REFERENCES Vlucht (vluchtnummer),
FOREIGN KEY (Balie) REFERENCES Balie (balienummer)
);


Vlucht tabel

/* Maak een table genaamd Vlucht */
CREATE TABLE Vlucht (
vluchtnummer	INTEGER	NOT NULL,
Maatschappij	CHAR(2)		NOT NULL,
Luchthaven	CHAR(3),
Gate		CHAR(1),
max_aantal	INTEGER	NOT NULL,
max_totaalgewicht NUMERIC(11,2)	NOT NULL,
max_ppgewicht	NUMERIC(5,2)	NOT NULL,
vertrektijdstip	DATE,
PRIMARY KEY  (vluchtnummer),
FOREIGN KEY (Luchthaven) REFERENCES Luchthaven (luchthavencode),
FOREIGN KEY (Gate) REFERENCES Gate (gatecode),
FOREIGN KEY (Maatschappij) REFERENCES Maatschappij (maatschappijcode)
);



Moet ik dan misschien een outerjoin doen?





EDIT: Nevermind. Weet je hoe stom.. ik moest gewoon helemaal geen GROUP BY namelijk.
@Gerben: Jouw probleem gaf precies aan waarom het stellen van de juiste vraag zo belangrijk is. 'alle passagiers van vlucht 4' heeft namelijk niks met tellen te maken, COUNT() valt dus af en hierdoor ook de GROUP BY.

Nog een kleine opmerking over het datamodel, CHAR(255) kan in MySQL niet, deze wordt automatisch omgezet naar een VARCHAR(255). Het gebruik van foreignkey's gebasseerd op een CHAR is ook sterk af te raden, dat maakt de database onnodig langzaam. Gebruik altijd integers voor dit soort zaken, tenzij het absoluut niet anders kan. En dat ben ik nog niet tegengekomen!

Edit: pgSQL, tja, die gaat natuurlijk niet creatief om met datatypes! Ik moet er nog aan wennen dat er hier mensen rondlopen die ook pgSQL gebruiken ;)
Dit is ook in postgresql, en je hebt gelijk. Maar dit is code van een jaar geleden, half overgenomen uit het boek.

Alleen er zaten al constraints in, dus daar wou ik even mee testen. (Blijft voorlopig alleen maar local want geen van m'n hosts draait pgsql)
Ik heb even de tutorial doorgenomen, en kwam eigenlijk ook achter dat ik geen group by nodig heb.
Ik wil gewoon alle gegevens uit tabel: berichten halen
en uit tabel: reactie wil ik de aantallen op de berichten halen.
dus eigenlijk heb ik toch geen group by nodig?
Dus heb ik deze regel verwijderd, maar nu doet hij het helemaal niet meer.
Ik ben nu helemaal in de war.

SELECT b.bericht_id, b.titel, b.datum, b.bericht, b.afbeelding, COUNT(r.reactie_id) AS aantal_reacties
FROM bericht as b left join reactie as r on b.bericht_id = r.bericht_id
ORDER BY b.bericht_id desc";

(sorry, ik weet niet hoe ik dit in zo'n vakje krijg)

wat doe ik nog steeds fout?
Je gebruikt COUNT(), een aggregate functie, dus ben je verplicht om GROUP BY te gebruiken wanneer je nog meer gegevens wilt opvragen. En dat wil jij.

Zet [ c ode ] en [ / code ] (zonder overbodige spaties) in de tekst om die fraaie vakjes te krijgen.
Je zult een subquery moeten gebruiken om het aantal te bepalen. Je kunt namelijk niet in 1 query zowel individuele gegevens als de eigenschappen van een groep ophalen:

SELECT
    b.bericht_id,
    b.datum,
    b.bericht,
    b.afbeelding,
    ( SELECT COUNT(reactie_id)
        FROM reactie
        WHERE bericht_id = b.bericht_id ) AS aantal
FROM
    bericht AS b
ORDER BY
    b.bericht_id DESC

Heb hem niet getest, maar volgens mij moet ie zo werken.
[edit]Komma vergeten :)[/edit]

Reageren