我的Django应用中有一个queryset
。查询集正在跨多个表访问信息,这些表中填充了产品信息(每个提供商的价格,名称,库存等...您在购物中发现的常用资料相关的应用程序。)
由于一种产品可以有多种价格,所以我最终得到了重复的产品。这实际上是合理且合乎逻辑的,因为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的产品?
答案 0 :(得分:1)
您可以使用子查询
$userid=$_GET['user'];
/////then run below query (leaving out mysqli function)
UPDATE users SET confirmed=1 WHERE user_id='$userid'
以下解决方案无法按照注释中的说明进行操作,因为您无法在过滤器中引用窗口功能
您应该可以用最低价格注释每个产品
min_query =
ProductPrice.objects.filter(product_id=OuterRef('id'))
.order_by('system_all_included_price')
.values('system_all_included_price', 'id')[:1]
queryset.annotate(
annotate_min_price=Subquery(
min_query.values('system_all_included_price')
).annotate(
annotate_min_id=Subquery(
min_query.values('id')
)
).order_by(ordering)
如果在某些情况下价格可以相等,那么您可能想再次遍历带注释的分区,以识别出最低的ID,然后根据匹配最低的ID进行过滤。
queryset.annotate(
annotate_min_price=Window(
expression=Min("prod_prices__system_all_included_price"),
partition_by=F('prod_prices__pk'),
order_by=ordering,
),
).filter(annotate_min_price=F('prod_prices__system_all_included_price)