За последние 24 часа нас посетили 9393 программиста и 1194 робота. Сейчас ищут 206 программистов ...

Проблемы с сортировкой из двух таблиц

Тема в разделе "MySQL", создана пользователем kuvalda, 5 июл 2013.

  1. kuvalda

    kuvalda Новичок

    С нами с:
    5 июл 2013
    Сообщения:
    3
    Симпатии:
    0
    Здравствуйте!

    Подскажите пожалуйста, есть такая проблемка..
    Пусть есть 2 таблицы:
    одна для страниц - pages (id, title, info),
    другая для фотографий прикрепленных к старницам - foto (id, filename, npp, id_pages).

    А атрибут foto.id_pages - внешний идентификатор от pages.id.

    foto.npp - порядковый номер фотографии относительно других фотографий конкретной страницы.

    Таким образом пример содержимого таблиц такой:
    pages
    Код (Text):
    1.  
    2. id       title      info
    3. 1      Новость1    текст1
    4. 2      Новость2    текст2
    foto
    Код (Text):
    1.  
    2. id      filename       id_pages           npp
    3. 1        abc.jpg             1              2
    4. 2        def.jpg             1              3
    5. 3         ghi.jpg            1              1
    6. 4         vxv.jpg            2              1
    А задачка такая - надо выводить из бд запись о странице pages и название файла первой фотографии по foto.npp.
    Делаю выборку страниц (например для списка новостей):
    Код (Text):
    1. SELECT pages.*, foto.filename FROM pages
    2. INNER JOIN foto ON foto.id_pages=pages.id
    3. GROUP BY pages.id
    4. ORDER BY pages.id desc, foto.npp ASC
    И почему-то для первой страницы фотку выдает все равно с foto.id=1 и foto.npp=2, т.е. первую по идентификатору..А должен же с foto.npp=1 ! Cортировку по npp игнорирует :-( Хотя если убрать group by, то список вывода будет правильным - отсортированным по foto.npp.
    Подскажите пожалуйста в чем моя ошибка? Может какие то нюансы SQL здесь надо знать?..

    Заранее спасибо!
     
  2. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    10.825
    Симпатии:
    1.174
    Адрес:
    там-сям
    это вы ошибаетесь в своих ожиданиях. работает как указали
     
  3. kuvalda

    kuvalda Новичок

    С нами с:
    5 июл 2013
    Сообщения:
    3
    Симпатии:
    0
    Спасибо за Ваш отклик.. Хм.. но у меня то результаты другие.. Может ли быть это связано с настройками MySQL или там версией? Или может это только глюк локального сервера...
     
  4. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    10.825
    Симпатии:
    1.174
    Адрес:
    там-сям
    Какие "другие"?

    Добавлено спустя 20 секунд:
    При группировке нельзя указывать любые поля для вывода, можно только те по которым группируете + агрегатные функции от других полей. а указывать * в запросе GROUP BY это просто свальный грех! То что при некоторых настройках MySQL позволяет вам такие вольности не гарантирует ошибок в будущем. Будте строже и ошибок не будет.

    Например, вот такой запрос правильный и выдаст предсказуемый результат:
    Код (Text):
    1. SELECT `id_pages`, MIN(`npp`) AS `npp` FROM `foto` GROUP BY `id_pages`
    Но если вы тупо добавите сюда поле filename, то это уже будет неправильный непредсказуемый запрос. Выкрутиться из положения можно если указанный запрос оформить как под-запрос.
    Код (Text):
    1. SELECT `pages`.*, `foto`.*
    2. FROM
    3.   (
    4.     SELECT `id_pages`, MIN(`npp`) AS `npp` FROM `foto` GROUP BY `id_pages`
    5.   ) AS `ff`
    6. INNER JOIN `foto` ON `ff`.`id_pages`=`foto`.`id_pages` AND `ff`.`npp`=`foto`.`npp`
    7. RIGHT JOIN `pages`  ON `pages`.`id`=`ff`.id_pages
    Здесь я предполагаю, что у некоторых страниц может не быть фото, тогда соответствующие поля будут выведены пустыми.

    Добавлено спустя 2 минуты 37 секунд:
    http://sqlfiddle.com/#!2/00bc1/1
     
  5. kuvalda

    kuvalda Новичок

    С нами с:
    5 июл 2013
    Сообщения:
    3
    Симпатии:
    0
    Другие - выводит первым с foto.id=1...
    Походу стоящие у меня раньше настройки MySQL позволяли это делать. Сейчас же вот нет.
    В принципе я Вас понял. Спасибо за советы.. Я тоже находил подобное решение с под-запросом, но подумал, что использовать под-запросы не оптимально, хотя мой запрос был более громоздкий, чем Ваш :)
    Буду пробовать тогда с подзапросами.. возьму на вооружение. Спасибо!)
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    10.825
    Симпатии:
    1.174
    Адрес:
    там-сям
    На здоровье.
    Кто сомневается в эффективности, может на sqlfiddle кликнуть ссылку View Execution Plan.