Как написать запрос типа "наибольший n на группу", но с дополнительными условиями?
Я задал вопрос о создании запроса типа "наибольший n для каждой группы" (в то время, когда он не знал, что он был назван "наибольший n на группу" ), за исключением того, что я спросил, как получить наименьшее количество для каждой группы. Структура таблицы была следующей:
type name value
=====================
1 item1 1
1 item2 20
2 item3 0
3 item4 5
3 item5 2
3 item6 50
Я получил несколько отличных ответов, и наиболее полезным было следующее:
SELECT t1.type, t1.name, t1.value
FROM mytable t1
LEFT JOIN mytable t2 ON t1.type = t2.type AND t1.value > t2.value
WHERE t2.value IS NULL
Вышеприведенный запрос приводит к следующему:
type name value
=====================
2 item3 0
1 item1 1
3 item5 2
Однако, задав этот вопрос, я понял, что я оставил важное требование, которое я, похоже, не могу понять, как добавить к вышеуказанному запросу. Мне нужно добавить условный оператор, который вместо выбора строки с наименьшим значением для столбца для каждой группы выбирает строку с наименьшим значением для столбца на группу, но там, где эта строка имеет другой столбец со значением, большим некоторого минимума стоимость.
Вот мой новый вопрос/проблема:
У меня есть следующая таблица (продукты):
+-----------------------------------------------------------+
| id | type | name | popularity | price |
+-----------------------------------------------------------+
| 0 | 0 | item1 | 3.5 | 0.99 |
| 3 | 1 | item2 | 3 | 1.99 |
| 4 | 1 | item3 | 6 | 2.95 |
| 6 | 1 | item4 | 9 | 2.50 |
| 9 | 1 | item5 | 12 | 3.75 |
| 12 | 2 | item6 | 16 | 5.25 |
| 13 | 2 | item7 | 32 | 10.95 |
| 14 | 2 | item8 | 48 | 7.50 |
+-----------------------------------------------------------+
Мне нужно получить наименьшую цену в каждой группе (группы, являющиеся разными значениями типа), причем ее популярность превышает некоторую сумму (если ни одна из групп в группе не имеет популярности больше указанной суммы, тогда нет предметов из этой группы следует вернуть). Последняя часть этого предложения заключается в том, как этот вопрос отличается от моего последнего вопроса. Предпочтительно результаты должны быть отсортированы по цене в порядке возрастания.
Итак, скажем, что популярность должна быть больше 3, тогда результат должен быть:
+-----------------------------------------------------------+
| id | type | name | popularity | price |
+-----------------------------------------------------------+
| 0 | 0 | item1 | 3.5 | 0.99 |
| 6 | 1 | item4 | 9 | 2.50 |
| 12 | 2 | item6 | 16 | 5.25 |
+-----------------------------------------------------------+
Если популярность должна быть больше 6, тогда результат должен быть:
+-----------------------------------------------------------+
| id | type | name | popularity | price |
+-----------------------------------------------------------+
| 6 | 1 | item4 | 9 | 2.50 |
| 12 | 2 | item6 | 16 | 5.25 |
+-----------------------------------------------------------+
Надеюсь, я правильно выполнил оба эти примера. В любом случае, я думаю, вы поняли.
Можно ли делать то, что я прошу в одном запросе?
Ответы
Ответ 1
Это требует некоторого внимания, где поставить условие (до where
или on
?), чтобы вы не обманули:-) Вам нужно добавить условие для t1 в where
и для t2 до on
:
SELECT t1.type, t1.name, t1.value
FROM mytable t1
LEFT JOIN mytable t2 ON t1.type = t2.type AND t1.value > t2.value
AND t2.popularity > 3 /* here */
WHERE t2.value IS NULL
AND t1.popularity > 3 /* and here */
Не тестировал, но он должен работать.
Попытка объяснения: условие, в котором предложение where влияет на элементы, которые вы считаете потенциальными элементами с наименьшим значением. Принимая во внимание, что условие в on
влияет на связь: на какие другие элементы вы хотите сравнить это? Он определяет группу, в которой вы сравниваете. Технически это влияет на то, когда t2. * Будет NULL. Если бы вы указали условие t2.popularity на where
вместо этого, вы бы не получили никаких NULL (т.е. Не находили элементы с наименьшим значением) для групп, в которых наименьшие элементы имеют низкую популярность.