Хочется поделиться интересной задачей на сообразительность, обычно я ее задаю на собеседовании. Задача интересна тем, что оказывается многие разработчики не знают, что выполняется раньше GROUP BY или ORDER BY.
Итак, имеем такую таблицу:
id (продавец автомобиля) | name (имя автомобиля) | price (цена) |
1 | bmw | 20 |
2 | bmw | 10 |
2 | audi | 30 |
3 | audi | 30 |
Задача: получить уникльный список автомобилей, минимальную цену по каждому авто и продавца, чтобы было понятней, вот ожидаемый результат:
id (продавец автомобиля) | name (имя автомобиля) | price (цена) |
2 | bmw | 10 |
2 | audi | 30 |
Простое решение
SELECT MIN(t.id), t.name, t.price
FROM t
INNER JOIN (
SELECT name, MIN (price) as price FROM t GROUP BY name
) t2 ON t2.name = t.name AND t2.price = t. price
GROUP BY t.name, t.price
думаю все понятно, но если нужны пояснения, пишите.
Немного сложнее
SELECT MIN(t.id), t.name, t.price
FROM t
LEFT JOIN t AS t2 ON t2.name = t.name AND t2.price < t.price
WHERE t2.price IS NULL
GROUP BY t.name, t.price
поясню: сначала мы нашли строки товаров, у которых t2.price будет равен NULL, потому что подумайте логически, ведь при джоине образуется такая price меньше которой быть не может, вот в этих строках и возникает NULL. Данный пример для сортировки ASC, а для сортировки DESC просто поменяйте знак меньше на больше.
DISTINCT vs GROUP BY
Оказывается про это тоже забывают, поэтому сразу ответ: по сути это одно и тоже, но GROUP BY дает возможность использовать HAVING:
SELECT id FROM t GROUP BY id HAVING COUNT(*) > 1
а вот дополнительно отфильтровать с помощью DISTINCT не выйдет.