Hallo,
Nun möchte ich immer 5 Rechnungen auf einmal anzeigen:
SELECT
rechnungen.kundennummer AS rekunr,
rechnungen.rechnungsnummer AS renr,
rechnungen.rechnungid AS reid,kundendaten.anrede AS kuan,
kundendaten.name AS kuna,
kundendaten.kundennummer AS kunr,positionen.rechnungsnummer AS ponr,
positionen.anzahl * positionen.preis AS gesamtFROM rechnungen
LEFT JOIN kundendaten
ON rechnungen.kundennummer = kundendaten.kundennummer
LEFT JOIN positionen
ON rechnungen.rechnungsnummer = positionen.rechnungsnummer
GROUP BY gesamt
ORDER BY rechnungen.rechnungsnummer
LIMIT $anzeige, 5
was für ein Glück, das nur MySQL ein derart fehlerhaftes Statement ausführt.
Was möchtest Du nun genau haben?
Jeweils die zusammengefaßten Daten von fünf Rechnungen?
Kundennummer,
Rechnungsnummer
Rechnungsid (wozu diese, wenn es eine Rechnungsnummer gibt?)
Werden Rechnungsnummern wiederverwendet? Wenn ja, darfst Du die Positionen auch nur über die rechnungid zuordnen.
Anrede
Name
und nochmals die Kundennummer (läßt man weg)
und nochmals die Rechnungsnummer (läßt man ebenfalls weg)
tja und dann den Rechnungsbetrag dieser einen Rechnung.
1. Schritt:
Berechne den Rechnungsbetrag jeder Rechnung (dazu benötigst Du die Aggregatsfunktion SUM(). Du benötigst nur die Tabelle positionen.
Gruppiere nach Rechnungsnummer.
2. Schritt:
Lass Dir die Rechnungsdetails anzeigen. Da die Zuordnung eindeutig sein sollte, und alle anderen Spalten der Tabelle Rechnung eindeutig von der Rechnungsnummer abhängen, könntest und solltest Du nach dem Join problemlos nach allen Spalten außer dem Rechnungsbetrag gruppieren.
3. Schritt
Die Kundendaten sollten ebenfalls eindeutig von der Rechnungsnummer abhängen, so dass Du problemlos die Kundendaten dazujoinen kannst und nach *allen* Spalten außer dem Rechnungsbetrag gruppieren kannst.
Ist Dir dies zuviel des Gruppierens, so joine die Rechnungstabelle mit der 1. Abfrage (Berechnung des Rechnungsbetrages) als temporärer View und anschließend die Kundendaten dazu. Durch den temporären View entfällt das weitere Gruppieren.
Du hast nach der einzigen Spalte gruppiert, nach der Du *nicht* gruppieren, sondern auf die Du eine Aggregatsfunktion anwenden solltest.
Ungetesteter Code für den Einsatz des temporären Views
1. Schritt:
Berechne den Rechnungsbetrag je Rechnung (Rechnungsnummer):
SELECT -- Gib mir
p.rechnungsnummer -- die Rechnungsnummer
SUM(p.anzahl * p.betrag) rechnungsbetrag -- und den Rechnungsbetrag,
-- der sich aus der Summe der Positionsbeträge
-- berechnet, die sich wiederum aus dem Produkt
-- von Einzelpreis und Anzahl berechnen
FROM -- aus der Tabelle
positionen p -- Positionen, die mit dem Alias p angesprochen wird
-- auf das optionale AS verzichten wir aus
-- Kompatibilitätsgründen :-)
GROUP BY -- gruppiert nach
p.rechnungsnummer -- den Rechnungsnummern, d.h. ein Eintrag je
-- Rechnungsnummer
Schritt 2:
Wir nutzen die Abfrage aus Schritt 1 als temporären View und joinen diese Abfrage mit der Rechnungstabelle:
SELECT -- Gib mir
r.rechnungsnummer, -- die Rechnungsnummer
r.kundennummer, -- die zugehörige Kundennummer
r.rechnungid, -- die Rechnungsid
p.rechnungsbetrag -- und den Rechnungsbetrag
FROM -- der
rp.rechnungen r -- Rechnungen, die wir bequemerweise über r
-- ansprechen. Verzicht auf AS siehe oben.
INNER JOIN ( -- die mit den Rechnungspositionen
SELECT -- aus Schritt 1
p.rechnungsnummer,
SUM(p.anzahl * p.preis) rechnungsbetrag
FROM
positionen p
GROUP BY
p.rechnungsnummer
) rp -- (der temporäre View benötigt zwingend einen
-- Aliasnamen (rp für rechnungspositionen))
ON -- über die
r.rechnungsnummer = rp.rechnungsnummer -- Rechnungsnummer verknüpft ist.
Die Vervollständigung mit den Kundendaten überlasse ich Dir als Übung.
Anmerkung: Vollständige Tabellennamen als Aliasnamen zu verwenden bzw. zur genauen Spaltenansprache, ist in den wenigsten Fällen sinnvoll und trägt meist nicht zur Lesbarkeit einer Abfrage bei.
Bei SQL-Problemen ist es nicht sinnvoll, PHP-Code zu posten, der SQL-Code erzeugt. Zuerst sollte man händisch das gewünschte SQL-Statement schreiben, bevor man versucht, es mit $programmiersprache zusammenzubauen. Es ist natürlich nicht notwendig, jeden benötigten LIMIT-Wert von Hand auszutesten :-)
Freundliche Grüße
Vinzenz