另一个表中存在按列排序并删除多余的行

时间:2019-02-27 23:52:18

标签: mysql sql laravel eloquent

我使用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`

2 个答案:

答案 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