порядок по столбцу существует в другой таблице и удаляет лишние строки - PullRequest
0 голосов
/ 28 февраля 2019

Я работаю с Laravel и MySQL, и у меня есть 2 таблицы: продукты и варианты

Каждый продукт имеет много вариантов, и у каждого варианта есть столбец цены.

Я хочу заказать товары по цене, чтобы объединить таблицы.

Но возникла проблема.продукты с 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 голосов
/ 28 февраля 2019

Если вы хотите получить доступ ко всем столбцам в записи, не агрегируйте.Вместо этого вы можете использовать коррелированный подзапрос для фильтрации только записи с наименьшей ценой.

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`
)

Примечание: я добавил псевдонимы таблиц в запрос, чтобы сделать его более читабельным.Также в этом выражении второе условие является избыточным, поэтому я удалил его.

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
0 голосов
/ 28 февраля 2019

вы можете использовать групповую функцию 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...