0

Есть таблицы:

offers

offer_id item_id is_main
1        1       1
2        1       0
3        1       0
4        2       0 
5        2       0
6        3       0
7        3       1

divisions

item_id     division_id
1           1
2           1
3           1

Есть запрос:

SELECT offers.offer_id , offers.item_id FROM offers
JOIN divisions ON offers.item_id = divisions.item_id
WHERE divisions.division_id IN (1)

Результат должен быть таким: offer_id (1, 4, 7), т.е. должен возвращаться только один offer_id от каждого item_id. Если существует offer_id с is_main = 1, то - он, если нет - то первый сортировкой по offer_id.

Как это реализовать?

lecherg
  • 319
  • http://ru.stackoverflow.com/questions/615714/sql-%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B8%D1%82%D1%8C-%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4-%D0%BE%D0%B4%D0%BD%D0%B0-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B0-%D0%BD%D0%B0-%D0%BA%D0%B0%D0%B6%D0%B4%D0%BE%D0%B5-%D0%B8%D0%BC%D1%8F/615766#615766 – Mike Jan 20 '17 at 09:02
  • в mysql select top 1 не работает – lecherg Jan 20 '17 at 09:18
  • А вы мой вариант от туда возьмите. он везде работает. а так то top в mysql надо заменить на limit 1 в конце запроса – Mike Jan 20 '17 at 09:24
  • не пойдет. Но уже разобрался: SELECT * FROM offers WHERE item_id IN (SELECT divisions.item_id FROM divisions WHERE divisions.division_id IN (1)) GROUP BY item_id ORDER BY offers.is_main – lecherg Jan 20 '17 at 09:37
  • @lecherg и вас не беспокоит, что этот запрос, во-первых, выдаёт некорректный результат, а во-вторых, в SELECT присутствуют столбцы, которые и не в агрегирующей функции, и не в GROUP BY? – Regent Jan 20 '17 at 09:40
  • еще как подойдет, надо только правильно применить. А ваш вариант если сработал на ваших данных - то вам повезло, без групповых функций возвращается первое попавшееся значение, если те же самые записи вставлять в таблицу в другом порядке - то результат может отличаться, т.к. он зависит от физического положения записей на диске – Mike Jan 20 '17 at 09:41
  • @Mike ваш вариант (второй из ответа) в MySQL 5.7, кстати, не работает, ибо в нём WHERE, а должен быть ON. В связи с чем вопрос: вы не против, если я размещу ответ на базе вашего решения с переименованиями? – Regent Jan 20 '17 at 09:44
  • разве coalesce(min(case when is_main=1 then offer_id),min(offer_id)) не работает ? при вашем group by конечно – Mike Jan 20 '17 at 09:45
  • @Regent А смысл, я тот поправил, там ON более уместен, конечно. А этот мне кажется по дублю надо будет закрыть, после того как у автора окончательно получится – Mike Jan 20 '17 at 09:47
  • @Mike если исправили, то можно и закрывать как дубликат. Кстати, как вы сами заметили в комментарии, для второго MAX (или MIN в данном вопросе) можно просто указать само поле, что уменьшает длину запроса на добрых пару десятков символов). Возможно, стоит и в ответе это сделать. – Regent Jan 20 '17 at 09:51
  • Ну и если всё же есть какие-то сложности с тем, чтобы взять и переименовать поля: SELECT d.item_id, COALESCE(MIN(CASE WHEN is_main = 1 THEN offer_id END), MIN(offer_id)) AS offer_id FROM divisions AS d LEFT JOIN offers AS o ON o.item_id = d.item_id GROUP BY d.item_id. – Regent Jan 20 '17 at 09:57
  • 1
    @Regent Я там и в вариант с top дописал версию с limit – Mike Jan 20 '17 at 10:00

0 Answers0