Hm, relativ aufwändig das in einer Datenbankabfrage zu realisieren.

Quick&Dirty würde ich das so machen, dass man anstatt max_forced noch 10 mehr auslesen lässt. Dann in der while-Schleife in PHP sich je Sponsor merken, wie viele Banner man schon ausgegeben hat, nach 3 dann weitere Banner vom Sponsor überspringen.

Kann dann allerdings dazu führen, dass am Ende weniger als max_forced Banner ausgegeben wurden, wenn bspw. nach der Sortierung (verdienst absteigend) mal 100 Banner eines Sponsors hintereinander kommen, aber max forced 15 ist.

Damit max forced erreicht wird, in einer weiteren Schleife erneut Banner auslesen (hier könnte man den Query erweitern, um Sponsoren, bei denen das Limit schon erreicht ist, gleich auszuschließen). Abbruchbedingung wäre dann, wenn der SELECT iwann 0 Datensätze liefert (alle Banner im Reload/max forced kann nicht mehr erreicht werden).
Evtl auch das Limit zum weiteren auslesen jedesmal verdoppeln, nicht dass man da massig Abfragen generiert, weil die Daten gerade den worst case darstellen ^^

Aber evtl. kommt ja noch wer mit einem performanten Query um die Ecke, der das auch so kann