Ich habe 2 Abfragen, die getrennt voneinander funktionieren. Wenn sie ähnlich sind, möchte ich sie zu einer performanten Abfrage zusammenfassen. Scheint einfach, da die Where-Klauseln ähnlich sind. Aber die Funktionen sum, count und min gelten alle für verschiedene Zeilen und stehen im Weg.Konsolidieren Sie 2 Abfragen mit ähnlichen Where-Klauseln, aber unterschiedlichen Aggregatfunktionszielen
Kontext:
- Benutzer können eine Position Note (oder Rate) und erhalten Punkte
- Ein Benutzer kann Benutzer B beziehen und Empfehlungspunkte erhalten, wenn Benutzer B zuerst eine Punktzahl nach
- Punkte verfallen einreicht ein bestimmtes Datum
- Ziel ist es, eine Rangliste der Benutzer und ihre Gesamtpunkte für das Scoring und Verweisen für einen bestimmten Standort (Bereich/Land)
- Positionsparameter sind mit harten v gefüllt Gültig für "Massachusetts", "United States" und das Ablaufdatum von scoreDateTime und sind in beiden Select-Subqueries leider doppelt vorhanden.
Frage:
Wie kann die Abfrage unter reorganisiert werden Einschränkungen zu kombinieren? Es muss eine Möglichkeit geben, mit einer Liste von Scores von einem bestimmten Ort nach einem bestimmten Datum zu beginnen. Die einzige Komplikation besteht darin, das erste Ergebnisdatum von Benutzer B zu erhalten und nur dann Benutzer A anzubieten, wenn es nach dem Ablaufdatum ist.
select scoring.userId, scoring.points + referring.points as leaderPoints
from (
select userId, sum(ratingPoints) as points
from scores s, locations l
where s.locationId = l.locationId and
l.locationArea = 'Massachusetts' and
l.locationCountry = 'United States' and
s.scoreDateTime > '2016-04-16 18:50:53.154' and
s.userId != 0
group by s.userId
) as scoring
join (
select u1.userId, count(*) * 20 as points
from users u0
join users u1 on u0.userId = u1.userId
join users u2 on u2.referredByEmail = u1.emailAddress
join scores s on u2.userId = s.userId
join locations l on s.locationId = l.locationId
where l.locationArea = 'Massachusetts' and
l.locationCountry = 'United States' and
scoreDateTime = (
select min(scoreDateTime)
from scores
where userId = u2.userId
) and
scoreDateTime >= '2016-04-16 18:50:53.154'
group by u1.userId
) as referring on scoring.userId = referring.userId
order by leaderPoints desc
limit 10;
Ich benutze MySQL, wo anscheinend CROSS APPLY scheint nicht zu gelten. Ich hoffte, die Beschränkungen locationArea, locationCountry und scoreDateTime zu konsolidieren, wenn sie dupliziert werden. Die einzige Zeit, die ich außerhalb dieser Liste von Punkten erreiche, ist die min (scoreDateTime), um die erste Punktzahl datetime des verwiesenen Benutzers zu erhalten. Ich möchte nur Empfehlungsbonuspunkte vergeben, wenn dieses Datum nach dem Stichtag liegt. – jmelvin
@jmelvin Ich habe die Antwort geändert, um Cross Apply zu entfernen. –