Hallo,
kann man einen Limit bei einer Abfrage über mehrere Tabellen hinweg auf eine Spalte einer Tabelle beschränken, wobei Wiederholungen des Spaltenwertes ignoriert werden?
Kurz gesagt geht es mir um etwas wie "LIMIT UNIQUE a.id 0,10".
Meine momentane Abfrage:
(Die Spalte "marken" in der Abonnenten-Tabelle ist ein VARCHAR-Feld, in dem die abonnierten Marken durch Kommata getrennt sind, also z. B. "3,2,31,19,7".)
Kurze Erklärung:
Die Abonnenten bestimmen selbst, über die Zugänge welcher Marken sie informiert werden wollen. Da es sehr viele Abonnenten und sehr viele Neuzugänge sind, wird der Versand aufgeteilt, sprich alle paar Minuten portionsweise abgearbeitet. (Im obigen Beispiel steht der Limit bei 10, wird aber dann auf 50 bis 100 erweitert.)
Wenn ich nun folgende Abfrage ausführe, erhalte ich natürlich genau bzw. max. 10 Einträge. Hat ein Abonnent A1 nun eine Marke abonniert und gibt es hier 4 Neueinträge, so sind das 4 Ergebniszeilen. Hat ein weiterer Abonnent A2 3 Marken abonniert und gibt es dort insgesamt 9 Neueinträge, so gibt es folglich 13 Ergebniszeilen.
Da der Limit bei 10 liegt, werden die 4 Einträge von A1 korrekt ausgegeben und versendet. Der Abonnent A2 erhält jedoch nur 6 der eigentlichen 9 Neueinträge. Je nachdem, wie ich das nun weiter fortführe, "entgehen" ihm entweder die restlichen 3 Einträge oder er erhält für diese restlichen 3 Einträge einen zweiten Newsletter. Beides ist natürlich inakzeptabel.
Nun würde ich die Abfrage gerne so gestalten, dass sich der Limit nicht auf die ersten 10 zutreffenden Ergebniszeilen bezieht, sondern auf die ersten 10 Abonnenten beschränkt wird, unabhängig davon, wie viele Neueinträge (Fahrzeuge) das zur Folge hat.
Für A1 gibt es 32 Neuzugänge
Für A2 gibt es 2 Neuzugänge
... (für A3 bis A9 gibt es jeweils 5 Neuzugänge)
Für A10 gibt es 0 Neuzugänge (wird folglich ignoriert)
Für A11 gibt es 54 Neuzugänge
Für A12 gibt es 7 Neuzugänge
Die Abfrage müsste dann insgesamt 123 Ergebniszeilen liefern (A12 muss ignoriert werden, da es der 11. zu berücksichtigende Abonnent ist).
Normalerweise würde man sowas ja mithilfe einer Gruppierung lösen, was hier aber natürlich so nicht geht, da ich dann folglich für jeden Abonnenten nur einen Eintrag erhalten würde. Auch könnte man das in 2 Abfragen aufteilen, also zuerst 10 Abonnenten holen und anschließend die Neueinträge für diese Abonnenten. Im Prinzip wäre das auch kein Problem. Dennoch interessiert es mich, ob man dieses Problem mit einer Abfrage lösen kann oder ob es unmöglich ist (was ich nicht ganz glaube). Von einer Lösung mittels PHP will ich ebenfalls absehen, da ich hierzu alle Ergebniszeilen holen müsste und diese bei mehreren Hundert Tausend liegen.
Kann mir jemand (auf die Sprünge) helfen? Vielen Dank schon mal.
pb
kann man einen Limit bei einer Abfrage über mehrere Tabellen hinweg auf eine Spalte einer Tabelle beschränken, wobei Wiederholungen des Spaltenwertes ignoriert werden?
Kurz gesagt geht es mir um etwas wie "LIMIT UNIQUE a.id 0,10".
Meine momentane Abfrage:
Code:
SELECT f.id AS fid, ..., a.id AS aid, ..., m.bez FROM kfz_marken m LEFT JOIN kfz_objekte f ON m.id=f.hersteller_id RIGHT JOIN newsletter_abonnenten a ON FIND_IN_SET(f.hersteller_id,a.marken) WHERE TO_DAYS(NOW())-TO_DAYS(f.datum)<7 AND f.aktiv=1 ... AND a.aktiv=1 ORDER BY a.id, m.id, f.id DESC LIMIT 0,10
Kurze Erklärung:
Die Abonnenten bestimmen selbst, über die Zugänge welcher Marken sie informiert werden wollen. Da es sehr viele Abonnenten und sehr viele Neuzugänge sind, wird der Versand aufgeteilt, sprich alle paar Minuten portionsweise abgearbeitet. (Im obigen Beispiel steht der Limit bei 10, wird aber dann auf 50 bis 100 erweitert.)
Wenn ich nun folgende Abfrage ausführe, erhalte ich natürlich genau bzw. max. 10 Einträge. Hat ein Abonnent A1 nun eine Marke abonniert und gibt es hier 4 Neueinträge, so sind das 4 Ergebniszeilen. Hat ein weiterer Abonnent A2 3 Marken abonniert und gibt es dort insgesamt 9 Neueinträge, so gibt es folglich 13 Ergebniszeilen.
Da der Limit bei 10 liegt, werden die 4 Einträge von A1 korrekt ausgegeben und versendet. Der Abonnent A2 erhält jedoch nur 6 der eigentlichen 9 Neueinträge. Je nachdem, wie ich das nun weiter fortführe, "entgehen" ihm entweder die restlichen 3 Einträge oder er erhält für diese restlichen 3 Einträge einen zweiten Newsletter. Beides ist natürlich inakzeptabel.
Nun würde ich die Abfrage gerne so gestalten, dass sich der Limit nicht auf die ersten 10 zutreffenden Ergebniszeilen bezieht, sondern auf die ersten 10 Abonnenten beschränkt wird, unabhängig davon, wie viele Neueinträge (Fahrzeuge) das zur Folge hat.
Für A1 gibt es 32 Neuzugänge
Für A2 gibt es 2 Neuzugänge
... (für A3 bis A9 gibt es jeweils 5 Neuzugänge)
Für A10 gibt es 0 Neuzugänge (wird folglich ignoriert)
Für A11 gibt es 54 Neuzugänge
Für A12 gibt es 7 Neuzugänge
Die Abfrage müsste dann insgesamt 123 Ergebniszeilen liefern (A12 muss ignoriert werden, da es der 11. zu berücksichtigende Abonnent ist).
Normalerweise würde man sowas ja mithilfe einer Gruppierung lösen, was hier aber natürlich so nicht geht, da ich dann folglich für jeden Abonnenten nur einen Eintrag erhalten würde. Auch könnte man das in 2 Abfragen aufteilen, also zuerst 10 Abonnenten holen und anschließend die Neueinträge für diese Abonnenten. Im Prinzip wäre das auch kein Problem. Dennoch interessiert es mich, ob man dieses Problem mit einer Abfrage lösen kann oder ob es unmöglich ist (was ich nicht ganz glaube). Von einer Lösung mittels PHP will ich ebenfalls absehen, da ich hierzu alle Ergebniszeilen holen müsste und diese bei mehreren Hundert Tausend liegen.
Kann mir jemand (auf die Sprünge) helfen? Vielen Dank schon mal.
pb
Kommentar