我使用laravel和MySQL,并且有2个表:产品和变体
每个产品都有很多变体,每个变体都有价格列。
我想按价格订购产品,以便加入表格。
但是有一个问题。具有3种变化的产品出现在3条记录中
products | price
----------------
1 | 10
1 | 11
2 | 21
2 | 22
2 | 23
所以我将结果与GROUP BY variations.product_id
分组。
products | price
----------------
1 | 11
2 | 23
但是我仍然有1个问题!我只需要一种价格最低的产品。
有人有主意吗?
laravel代码:
$this->builder->join('variations', 'variations.product_id',
'=',
'products.id')
->select('products.*')
->groupBy('variations.product_id')
->orderBy('variations.discounted_price', 'Desc');
产生的SQL代码
select `products`.* from `products` inner join `variations`
on `variations`.`product_id` = `products`.`id`
group by `variations`.`product_id` order by `variations`.`discounted_price`
答案 0 :(得分:1)
您可以使用组函数MIN()
完成此操作
我正在对您的查询进行假设,以说明这一点。
SELECT `products`.`id`,MIN(`variations`.`price`) AS `price`
FROM `products`
JOIN `variations` on `variations`.`product_id` = `products`.`id`
GROUP BY `products`.`id`
如果您只需要一个,只需添加ORDER BY price ASC LIMIT 1
编辑:根据您的代码,尝试
$this->builder->join('variations', 'variations.product_id',
'=',
'products.id')
->select('products.*')
->groupBy('variations.product_id')
->orderBy('variations.discounted_price', 'Asc')
->first();
答案 1 :(得分:1)
如果要访问记录中的所有列,请不要汇总。相反,您可以使用相关子查询仅过滤价格最低的记录。
SELECT p.*, v.`discounted_price`
FROM `products` p
INNER JOIN `variations` v ON v.`product_id` = p.`id`
WHERE p.`category_id` = 14
AND NOT EXISTS (
SELECT 1
FROM `variations` v1
WHERE
v1.`product_id` = v.`product_id`
AND v1.`discounted_price` < v.`discounted_price`
)
注意:我在查询中添加了表别名,以使其更具可读性。同样在此表达式中,第二个条件是redondant,因此我将其删除。
p.`category_id` = 14 and p.`category_id` is not null
在MySQL 8.0中,您可以使用窗口函数ROW_NUMBER()
来更有效地进行过滤:
SELECT *
FROM (
SELECT
p.*,
v.`discounted_price`,
ROW_NUMBER() OVER(PARTITION BY v.`product_id` ORDER BY v.`discounted_price`) rn
FROM `products` p
INNER JOIN `variations` v on v.`product_id` = p.`id`
WHERE p.`category_id` = 14
) x WHERE rn = 1