Выберите DISTINCT, возвращая слишком много записей
У меня есть две таблицы: продукты и предметы. Я хочу выбрать distinct
предметы, которые относятся к продукту на основе condition
столбец, отсортировано по price ASC
,
+-------------------+
| id | name |
+-------------------+
| 1 | Mickey Mouse |
+-------------------+
+-------------------------------------+
| id | product_id | condition | price |
+-------------------------------------+
| 1 | 1 | New | 90 |
| 2 | 1 | New | 80 |
| 3 | 1 | Excellent | 60 |
| 4 | 1 | Excellent | 50 |
| 5 | 1 | Used | 30 |
| 6 | 1 | Used | 20 |
+-------------------------------------+
Желаемый результат:
+----------------------------------------+
| id | name | condition | price |
+----------------------------------------+
| 2 | Mickey Mouse | New | 80 |
| 4 | Mickey Mouse | Excellent | 50 |
| 6 | Mickey Mouse | Used | 20 |
+----------------------------------------+
Вот запрос. Возвращает шесть записей вместо желаемых трех:
SELECT DISTINCT(items.condition), items.price, products.name
FROM products
INNER JOIN items ON products.id = items.product_id
WHERE products.id = 1
ORDER BY items."price" ASC, products.name;
4 ответа
Правильный запрос PostgreSQL:
SELECT DISTINCT ON (items.condition) items.id, items.condition, items.price, products.name
FROM products
INNER JOIN items ON products.id = items.product_id
WHERE products.id = 1
ORDER BY items.condition, items.price, products.name;
SELECT DISTINCT ON (выражение [, ...]) сохраняет только первую строку каждого набора строк, где заданные выражения оцениваются как равные.
подробности here
Здесь нет distinct()
функция в SQL. Ваш запрос анализируется как
SELECT DISTINCT (items.condition), ...
что эквивалентно
SELECT DISTINCT items.condition, ...
DISTINCT
применяется ко всей строке - если две или более строки имеют одинаковые значения поля, ТО "дублирующаяся" строка удаляется из результирующего набора.
Вы, вероятно, хотите что-то более похожее
SELECT items.condition, MIN(items.price), products.name
FROM ...
...
GROUP BY products.id
Я хочу выбрать отдельные товары, которые принадлежат продукту, на основе столбца условий, отсортированного по цене.
ASC
,
Вы, скорее всего, хотите DISTINCT ON
:
SELECT *
FROM (
SELECT DISTINCT ON (i.condition)
i.id AS item_id, p.name, i.condition, i.price
FROM products p
JOIN items i ON i.products.id = p.id
WHERE p.id = 1
ORDER BY i.condition, i.price ASC
) sub
ORDER BY item_id;
Поскольку ведущие колонны ORDER BY
должны соответствовать столбцы, используемые в DISTINCT ON
вам нужен подзапрос, чтобы получить отображаемый порядок сортировки.
Еще лучше:
SELECT i.item_id, p.name, i.condition, i.price
FROM (
SELECT DISTINCT ON (condition)
id AS item_id, product_id, condition, price
FROM items
WHERE product_id = 1
ORDER BY condition, price
) i
JOIN products p ON p.id = i.product_id
ORDER BY item_id;
Должно быть немного быстрее.
В сторону: вы не должны использовать неописательное имя id
в качестве идентификатора. использование item_id
а также product_id
вместо.
Более подробная информация, ссылки и тест в этом ответе:
Выберите первую строку в каждой группе GROUP BY?
Используйте SELECT GROUP BY, извлекая только МИНУТУ (цену) для каждого ИЗДЕЛИЯ / СОСТОЯНИЯ.