SELECT o.OrderID
CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN
o.NegotiatedPrice
ELSE
o.SuggestedPrice
END AS Price
Один из способов, который вы можете порекомендовать, какие достижения использовать, - это посмотреть, сколько ваших пользователей уже имеют эти достижения, и порекомендовать те популярные. Когда они достигнуты, вы спускаетесь по списку и рекомендуете менее популярные. Однако у этого есть наивное предположение, что все хотят стремиться к народным достижениям. Это может привести к тому, что популярные достижения станут еще более популярными и менее популярными, ну ... Утешает то, что это не требует много ресурсов и, вероятно, будет выполняться очень быстро. (Просто ведите список достижений + количество их достижений)
Другой метод (который пытается угадать, каких достижений может достичь пользователь, основываясь на том, какие достижения у него уже были) - использовать некоторые алгоритмы машинного обучения. Я думаю, что алгоритм k-ближайшего соседа будет работать здесь достаточно хорошо. Выберите порог и просто выведите все, что выше этого порога. Я не знаю, будет ли это работать быстрее, чем то, что у вас уже есть, но вы должны просто запускать механизм рекомендаций один раз, когда пользователь делает новое достижение, сохраняйте лучшие (скажем,) пять, и просто выводите его обратно пользователю, когда потребуется рекомендация.
Надеюсь, это поможет. =)
Я бы посоветовал вам выполнить первые три шага (достижения, другие алиасы, подсчет) как один оператор SQL. В настоящее время вы отправляете множество запросов и суммируете тысячи строк в Python, что является задачей, которую вы должны делегировать БД. Например, код
for otherAlias in otherAliases : #For every single other user
for otherAch in otherAlias.achievements.all() : #execute a query
r[otherAch] = r.get(otherAch, 0) + 1
выполняет тысячи огромных запросов.
Вместо этого вы можете использовать SQL для этого, присоединив Achiever к самому себе на основе другого идентификатора псевдонима и такого же идентификатора достижения. Затем вы группируете по идентификатору достижения и запускаете подсчет.
В приведенном ниже запросе таблица «B» - это достижения других пользователей, а «Achiever» - наши достижения. Если какой-либо другой пользователь делится достижением, он появляется один раз в «Б» для каждого общего достижения. Затем мы группируем их по alias_id и подсчитываем, сколько раз они появлялись, чтобы получить хороший идентификатор, подсчитать таблицу.
Очень, очень грубый код (здесь нет SQL)
SELECT B.Alias_id, COUNT(B.achievement_id)
FROM Achiever, Achiever as B
WHERE Achiever.achievement_id == B.achievement_id
AND Achiever.Alias_id == <insert current user alias here>;
GROUP BY B.Alias_id
Если это сработает, я думаю, что это будет , вы получите таблицу других псевдонимов пользователей, а также количество достижений, которыми они делятся с текущим пользователем.
Следующее, что вы делаете, - это оператор SQL, который использует приведенный выше как «внутренний выбор» - назовите его пользователей. Вы присоединяетесь к этой таблице со своей таблицей достижений и таблицей достижений текущего пользователя. Возможно, вы захотите проигнорировать всех, кроме 10 лучших пользователей, которые похожи на текущего пользователя.
У меня нет времени писать хороший запрос прямо сейчас, но посмотрите на оператор JOIN для вашей БД, который присоединяется по достижению_id между назначенными 10 пользователями и текущим пользователем - установка этого идентификатора на NULL, если это не так. не существует. Фильтр только для строк, в которых он оказался NULL (недостигнутые достижения).