2016-08-19 8 views
2

Ich arbeite mit Geld Ablaufverfolgung Problem im Moment (ursprünglich ist es kein Geld, aber ich habe es als ein bequemeres Beispiel verwendet).Geld Ablaufverfolgung

Ein Benutzer kann aus einem mysteriösen Grund Geld von einer Plattform verdienen und sie für den Kauf von Sachen (Produkte, Geschenke usw.) ausgeben.

Ich suche einen Algorithmus (SQL-Abfrage besten Fall), um ein aktuelles Kontostand einer Benutzerbilanz zu finden.

Die Ereignisse der Ausgaben und Geld zu verdienen, andere Datenbank (MySQL ) Tabellen gespeichert sind (sie user_earned und user_spent sagen). Im Normalfall würde ich einfach die Benutzergesamtwerte von user_earned zählen und das ausgegebene Geld abziehen (insgesamt user_spent).

ABER! Es gibt eine Bedingung, dass verdiente Benutzer Geld in 2 Jahren verfällt, wenn sie nicht verwendet werden. Das bedeutet, wenn der Benutzer sein Geld nicht verwendet oder nur einen Teil davon verwendet hat, verfallen diese. Wenn ein Benutzer sein Geld verwendet, werden sie aus dem ältesten nicht abgelaufenen Geldsatz verwendet, so dass der Saldo (Bonus) zu Gunsten des Benutzers berechnet werden konnte.

Dies sind 5 Szenarien mit Ereignissen in der Zeit, über den Fall ein besseres Verständnis zu haben:

Money expiration logic

Beiden Tabellen (user_earned und user_spent) haben Zeitstempel für Terminverfolgung.

+0

Dies kann eine Aufgabe sein, die am besten im Anwendungscode ausgeführt wird. –

+0

Derzeit habe ich einen Dienst implementiert, der die Bilanz berechnet, indem er einfach eine Liste von Ereignissen (Empfang, Verwendung, Ablauf) erstellt und sie nacheinander ausführt. Es funktioniert, aber für den Fall, dass ich das Gleichgewicht in einer SQL-Abfrage benötigte, um Benutzer mit einem positiven Saldo zu erhalten, müsste ich diesen Wert vorher für die Datenbank denormalisieren. – Aistis

Antwort

1

Ich habe etwas ähnliches in einem meiner Projekte getan.

Sieht aus wie Sie eine zusätzliche Tabelle spends_covering mit Spalten spend_id, earhed_id benötigen, sum

Also für jeden spends Datensatz müssen Sie eine oder mehrere Zeilen in die spends_covering einfügen Geld ‚gebraucht‘ zu markieren.

Dann Gleichgewicht wäre nur Summe von nicht verwendet, wo Datum ist weniger als 2 Jahre.

select sum(sub.earned_sum-sub.spent_sum) as balance 
from 
    (select e.sum as earned_sum, sum(sc.sum) as spent_sum 
    from earned e 
     left join spends_covering sc on e.earhed_id=sc.earhed_id 
    where e.date BETWEEN ... 
    group by e.earhed_id 
    having earned_sum > spent_sum) sub 
0

Es kann sich lohnen, zwei Tabellen zu haben - eine (oder mehrere) mit allen historischen Details, eine nur mit den aktuellen Salden für jeden ‚Benutzer‘. Achten Sie darauf, Transaktionen zu verwenden, um die beiden synchron zu halten.