У меня есть queryset
в моем приложении Django. Набор запросов обеспечивает доступ к информации из нескольких таблиц, заполненных информацией о продуктах ( цена на одного поставщика , название, запас и т. Д.) обычный материал, который можно найти в связанных с покупками товарах приложение).
Поскольку один продукт может иметь несколько цен, я получаю дубликаты. Это на самом деле хорошо и логично, так как SQL просто показывает мне столько же продублированных продуктов, сколько и цены каждого продукта.
Вот где я использую агрегаты:
queryset.annotate(
annotate_min_price=Min("product_prices__price"),
)
Это заставляет мой набор запросов возвращать только самую низкую цену для каждого продукта, что предотвращает дублирование продуктов.
На данный момент запрос выглядит так:
SELECT DISTINCT
"prod_prod"."id",
...
MIN ( "monetary_prodprice"."system_all_included_price" ) AS "annotate_min_price"
FROM
"prod_prod"
INNER JOIN "monetary_prodprice" ON ( "prod_prod"."id" = "monetary_prodprice"."prod_id" )
INNER JOIN "monetary_pricelist" ON ( "monetary_prodprice"."pricelist_id" = "monetary_pricelist"."id" )
INNER JOIN "monetary_pricelistdestinations" ON ( "monetary_pricelist"."id" = "monetary_pricelistdestinations"."pricelist_id" )
INNER JOIN "prodtransaction_carrier_pricelists" ON ( "monetary_pricelist"."id" = "prodtransaction_carrier_pricelists"."pricelist_id" )
INNER JOIN "prodtransaction_carrier" ON ( "prodtransaction_carrier_pricelists"."carrier_id" = "prodtransaction_carrier"."id" )
INNER JOIN "prodtransaction_carrierdelivery" ON ( "prodtransaction_carrier"."id" = "prodtransaction_carrierdelivery"."carrier_id" )
INNER JOIN "monetary_pricelistcountry" ON ( "monetary_pricelist"."id" = "monetary_pricelistcountry"."pricelist_id" )
WHERE
(
...
)
GROUP BY
"prod_prod"."id",
ORDER BY
"annotate_min_price" DESC
Проблема в том, что, кроме самой низкой цены, мне нужно получить действительную ID
этой цены. Поэтому я изменяю свой набор запросов соответственно:
queryset.annotate(
annotate_min_price=Min("prod_prices__system_all_included_price"),
annotate_best_price=F('prod_prices__pk')).order_by(ordering)
Вот тут я и решаю проблему. Это даст следующий запрос:
SELECT DISTINCT
"prod_prod"."id",
...
MIN ( "monetary_prodprice"."system_all_included_price" ) AS "annotate_min_price",
"monetary_prodprice"."id" ) AS "annotate_best_price"
FROM
"prod_prod"
INNER JOIN "monetary_prodprice" ON ( "prod_prod"."id" = "monetary_prodprice"."prod_id" )
INNER JOIN "monetary_pricelist" ON ( "monetary_prodprice"."pricelist_id" = "monetary_pricelist"."id" )
INNER JOIN "monetary_pricelistdestinations" ON ( "monetary_pricelist"."id" = "monetary_pricelistdestinations"."pricelist_id" )
INNER JOIN "prodtransaction_carrier_pricelists" ON ( "monetary_pricelist"."id" = "prodtransaction_carrier_pricelists"."pricelist_id" )
INNER JOIN "prodtransaction_carrier" ON ( "prodtransaction_carrier_pricelists"."carrier_id" = "prodtransaction_carrier"."id" )
INNER JOIN "prodtransaction_carrierdelivery" ON ( "prodtransaction_carrier"."id" = "prodtransaction_carrierdelivery"."carrier_id" )
INNER JOIN "monetary_pricelistcountry" ON ( "monetary_pricelist"."id" = "monetary_pricelistcountry"."pricelist_id" )
WHERE
(
...
)
GROUP BY
"prod_prod"."id",
"monetary_prodprice"."id"
ORDER BY
"annotate_min_price" DESC
Это заставляет мой набор запросов дублировать продукты. Я понимаю, что это происходит потому, что я прошу PostgreSQL добавить ID
цен к каждой строке (продукту), и это как-то нарушает агрегатор MIN
.
Мой вопрос: как я могу заставить Django возвращать только продукты с самой низкой ценой и ID этой цены одновременно?