Используйте JOIN пользователей с покупками, GROUP BY, HAVING COUNT(*) > 5 и LIMIT 10 после сортировки по убыванию количества. Считать нужно записи Purchase, не сумму count_products.
Выборка топ‑10 покупателей с более чем пятью покупками
Используйте JOIN пользователей с покупками, GROUP BY, HAVING COUNT(*) > 5 и LIMIT 10 после сортировки по убыванию количества. Считать нужно записи Purchase, не сумму count_products.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Переписать запрос, использующий ORM, в чистый SQL. Нужно получить десять пользователей, у которых количество записей в таблице Purchase превышает пять.
class User(db.Models):
name = models.CharField(
max_length=256,
blank=True,
default="",
verbose_name="Имя"
)
class Product(db.Models):
name = models.CharField(
max_length=256,
blank=True,
default="",
verbose_name="Название"
)
price = models.DecimalField()
class Purchase(db.Models):
user = models.ForeignKey(
model=User,
related_name="purchase",
on_delete=models.CASCADE
)
product = models.ForeignKey(
model=Product,
related_name="purchase",
on_delete=models.CASCADE
)
count_products = models.IntegerField(default=1)
users = User.objects.annotate(
count_purchases=Count(Purchase.objects.all())
).exclude(
count_purchases__lte=5
).order_by(
"-count_purchases"
)[:10]
Ответ
Используйте JOIN пользователей с покупками, GROUP BY, HAVING COUNT(*) > 5 и LIMIT 10 после сортировки по убыванию количества. Считать нужно записи Purchase, не сумму count_products.
Пример с условными физическими именами таблиц:
SELECT u.id, u.name, COUNT(p.id) AS count_purchases
FROM users AS u
JOIN purchases AS p ON p.user_id = u.id
GROUP BY u.id, u.name
HAVING COUNT(p.id) > 5
ORDER BY count_purchases DESC, u.id
LIMIT 10;
Настоящие имена Django-таблиц зависят от приложения и db_table. Исходное Count(Purchase.objects.all()) не является корректным подсчётом связей: в ORM здесь нужен Count('purchase'). Вторичный порядок по id делает выбор первой десятки устойчивым при одинаковом числе покупок.