Как написать запрос типа "наибольший 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 (т.е. Не находили элементы с наименьшим значением) для групп, в которых наименьшие элементы имеют низкую популярность.