MySQL - Blättermenü erstellen - Verständnisproblem
I Carsten
- datenbank
Guten Abend!
Zur (langen) Erklärung, ich habe 2 Tabellen:
tblUsers: tblOrders:
| Benutzername | Id | und | RNr | UserId | id |
--------------------- ---------------------
| foo | 1 | | 1a | 1 | 1 |
| bar | 1 | | 1b | 1 | 2 |
--------------------- ---------------------
Es besteht eine 1:n Beziehung.
Ein Benutzer kann eine Rechnungsnummer haben, muss aber nicht.
Jeder Rechnungsnummer ist aber genau 1 Kunden zugeordnet.
Ich möchte meine Daten jeweils unter folgenden Bedingungen:
1a. alle Daten aus tblUsers
1b. nur Daten aus tblUsers (+tblOrders) denen Daten aus tblOrders zugeordnet sind
Für 1a brauch ich nur eine Abfrage über die gesamte Tabelle tblUsers.
Für 1b muss ich beide Tabellen ansprechen und wahrscheinlich durchsucht die Datenbank auch beide Tabellen vollständig.
Nun möchte ich mir ein Blättermenü erstellen, dass x Benutzer pro Seite auflistet. Dabei ist mir dann aufgefallen...
Für das Menü benötige ich die Menge der Datensätze für die Varianten 1a oder 1b.
Für die Darstellung von 1b mit dem Blättermenü brauch ich aber nur die Datensätze aus tblOrders, welche auf der aktuellen Seite angezeigt werden müssen.
Und jetzt kommt endlich meine Frage ;)
Sollte ich für die Generierung des Blättermenüs beide Tabellen abfragen und alle Daten speichern, so dass ich bereits _alle_ Datensätze vollständig habe?
Oder sollte ich für das Menü 1 Abfrage starten (jeweils 1a o. 1b) und 1 weitere für die betroffenen Datensätze?
Ich find es gerade irritierend, dass ich nur für das Blättermenü alle Daten abfragen muss obwohl ich aus tblOrders nur die Datensätze der gewählten Seite brauch.
I Carsten
مرحبا
Sollte ich für die Generierung des Blättermenüs beide Tabellen abfragen und alle Daten speichern, so dass ich bereits _alle_ Datensätze vollständig habe?
Kommt doch auf dein Blättermenü an, wenn du nur einen Link zum vorwärts, und einen Link zum Rückwärtsblättern generierst, brauchst du nicht alle Datensätze, nur weiss dann auch der User nicht, wann und ob das blättern überhaupt ein ende findet.
Oder sollte ich für das Menü 1 Abfrage starten (jeweils 1a o. 1b) und 1 weitere für die betroffenen Datensätze?
Du kannst das zählen ja nebenher mit SQL_CALC_FOUND_ROWS
erledigen.
Ich find es gerade irritierend, dass ich nur für das Blättermenü alle Daten abfragen muss obwohl ich aus tblOrders nur die Datensätze der gewählten Seite brauch.
Das script, dass die Links generiert, muss ja wissen, wieviele Datensätze es gibt, um dementsprechend die Links zu generieren.
Ich habe mir vor kurzem eine Klasse geschrieben, die so ein Menu generiert, dafür benötigt es aber die anzahl aller Datensätze, da es sonst nicht rechnen kann.
mfg
Hallo Malcolm Becks,
Ich habe mir vor kurzem eine Klasse geschrieben, die so ein Menu generiert, dafür benötigt es aber die anzahl aller Datensätze, da es sonst nicht rechnen kann.
genau darum geht es mir ja.
Ich muss erst alle Datensätze einlesen, um die Anzahl ermitteln zu können.
Das geht übrigens auch später mit count(), da die Weiterverarbeitung von PHP übernommen wird.
Ist das nicht ein bisschen umständlich immer erst alle Datensätze einlesen zu müssen, nur um die gewünschten paar angezeigt zu bekommen?
Deine Klasse in allen Ehren (bzw. das Beispiel), gefällt mir recht gut, an der Umsetzung allgemein hapert es aber nicht unbedingt. Ich hab wohl eher Verständnisprobleme mit dem Konzept.
Wenn ich aber tatsächlich immer alle Datensätze einlesen muss, obwohl z.B. nur 10 angezeigt werden sollen, dann ist das halt so ;)
I Carsten
مرحبا Carsten
Ich muss erst alle Datensätze einlesen, um die Anzahl ermitteln zu können.
Das geht übrigens auch später mit count(), da die Weiterverarbeitung von PHP übernommen wird.
Deswegen schrieb ich ja "SQL_CALC_FOUND_ROWS".
Ich weiss nicht, ob es am count() liegt, aber fast alle Scripte (die ich so gesehen habe), die mit count() Blättermenus generieren, brauchen ein zusätzliches Select-Statement, um die Datensätze zählen zu können, "SQL_CALC_FOUND_ROWS" liefert dir die Limitierten Daten und die anzahl aller in einem Statement.
Ist das nicht ein bisschen umständlich immer erst alle Datensätze einlesen zu müssen, nur um die gewünschten paar angezeigt zu bekommen?
Das ist sehr umständlich und auch nicht nötig.
Deine Klasse in allen Ehren (bzw. das Beispiel), gefällt mir recht gut, an der Umsetzung allgemein hapert es aber nicht unbedingt. Ich hab wohl eher Verständnisprobleme mit dem Konzept.
Es dient als einfaches Bsp., wie stellst du dir dein Menu vor, wie soll die bedienung aussehen? Wenn du Bspw. ab der ersten Seite auch auf die letzte Seite der generierten Seiten verlinken willst (wie bei mir), kommst du nicht drum herum, die Anzahl der Daten zu wissen.
Wenn ich aber tatsächlich immer alle Datensätze einlesen muss, obwohl z.B. nur 10 angezeigt werden sollen, dann ist das halt so ;)
SQL_CALC_FOUND_ROWS ist das Stichwort.
mfg
Hallo Malcolm Becks,
danke für den Hinweis auf SQL_CALC_FOUND_ROWS! Das sieht eigentlich ganz vernünftig aus.
Ich möchte aber leider nicht die einzelnen Rechnungen auf die Seiten verteilen, sondern die Benutzernamen.
Z.B. 10 Benutzer pro Seite anzeigen und die dazugehörigen Rechnungen.
Wenn ich aber die Rechnungen zusammen mit den Benutzernamen abfrage, liefert mir SQL_CALC_FOUND_ROWS natürlich die Menge der Rechnungsnummern und nicht die der _verschiedenen_ Benutzer.
Zur Verdeutlichung vielleicht hier mein Statement zur Abfrage der Daten
SELECT tblUsers.Id userId,
tblUsers.Benutzername userName,
tblOrders.Id rechnungsId,
tblOrders.RNr rechnungsNummer
FROM (SELECT Id, Benutzername
FROM tblUsers
ORDER BY Id DESC
LIMIT 0, 10)
tblUsers
LEFT JOIN tblOrders
ON tblUsers.Id = tblOrders.UserId
ORDER BY tblUsers.Id DESC, tblOrders.Id
Irgendwie komm ich da mit SQL_CALC_FOUND_ROWS nicht weiter.
I Carsten
مرحبا Carsten
> SELECT tblUsers.Id userId,
> tblUsers.Benutzername userName,
> tblOrders.Id rechnungsId,
> tblOrders.RNr rechnungsNummer
> FROM (SELECT Id, Benutzername
> FROM tblUsers
> ORDER BY Id DESC
> LIMIT 0, 10)
> tblUsers
> LEFT JOIN tblOrders
> ON tblUsers.Id = tblOrders.UserId
> ORDER BY tblUsers.Id DESC, tblOrders.Id
In welchem query hast du SQL_CALC_FOUND_ROWS angewendet?
Ich hab's nicht getestet, aber ich denke mal, wenn count() in Subquerys funktioniert, müsste es mit SQL_CALC_FOUND_ROWS auch funktionieren.
mfg
In welchem query hast du SQL_CALC_FOUND_ROWS angewendet?
In beiden. Im ersten zählt es halt alle Datensätze, im zweiten
Ich hab's nicht getestet, aber ich denke mal, wenn count() in Subquerys funktioniert, müsste es mit SQL_CALC_FOUND_ROWS auch funktionieren.
funktioniert es (aber) nicht. Die Fehlermeldung hab ich nicht im Kopf, aber es war an der Stelle nicht erlaubt.
I Carsten
Hi,
Ich muss erst alle Datensätze einlesen, um die Anzahl ermitteln zu können.
Das geht übrigens auch später mit count(), da die Weiterverarbeitung von PHP übernommen wird.Ist das nicht ein bisschen umständlich immer erst alle Datensätze einlesen zu müssen, nur um die gewünschten paar angezeigt zu bekommen?
Ja, eben - wieso willst du es dann machen?
Erst im PHP-Script die Datensätze zu zählen, ist eine ganz blöde Idee - dazu musst du sie nämlich auch alle erst dorthin „rüberschaufeln“.
Wenn ich aber tatsächlich immer alle Datensätze einlesen muss, obwohl z.B. nur 10 angezeigt werden sollen, dann ist das halt so ;)
Nein, so ist es ganz und gar nicht.
Beschäftige dich mit Aggregatfunktionen der Datenbank, und auch mit dem erwähnten SQL_CALC_FOUND_ROWS.
MfG ChrisB
Hallo,
wie es aussieht, brauch ich wohl mindestens 2 Abfragen.
Ich denke also über einen anderen Ansatz nach.
Zunächst SELECT auf die Namen, ggf. mit LIMIT für das Blättermenü, und
eine weitere Abfrage nach den Rechnungen für die gefundenen Datensätze.
Nun ist die Frage, wie ich die zweite Abfrage gestalte.
Kann ich das Ergebnis der ersten Abfrage "zwischenspeichern", so dass ich die zweite Abfrage in der Form SELECT [..] WHERE UserId IN (-erstes Result-)[..]
schreiben kann?
I Carsten