Помогите со сложным запросом

Тема в разделе "Базы данных", создана пользователем askarbin, 20 окт 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. askarbin

    askarbin

    Регистр.:
    31 мар 2009
    Сообщения:
    292
    Симпатии:
    36
    Прошу помощи, бьюсь над запросом уже второй день ничего придумать не могу, даже в связке с пхп путевого ничего не приходит на ум.
    1. Суть такова:
    Есть две таблицы (objects и typeobject) в objects есть поле type (int), в котором лежат id типов объектов из таблицы typeobject. В typeobject есть три поля id, name, parent.
    Если parent = 0, то раздел родительский, если parent != 0, то значение parent указывает на родительский раздел (у которого parent = 0).
    2. Задача:
    Необходимо сформировать запрос таким образом, чтобы на выходе получить все родительские разделы типов, для которых в таблице objects существуют объекты (поле type) с учетом дочерних типов объектов.
    3. Пример (на котором я споткнулся:(
    У меня есть родительская категория "Родительская категория1" и есть ее дочерняя категория "Дочерняя категория1" и по аналогии есть другая "Родительская категория2" и ее "Дочерняя категория2".
    В первом случае у меня в таблице objects есть объекты с типом Родительская категория1 и (есть или нету, это не важно) объекты с типом Дочерняя категория1. В таком случае запрос очень простой и у меня все получается.
    Во втором случае у меня в таблице objects есть объекты с типом Дочерняя категория2 и нету объектов с типом Родительская категория2. Но тем не менее объекты для этой родительской категории есть и тут мой запрос спотыкается и уже не выводит мне Родительскую категорию2 в меню.

    Подскажите, пожалуйста, как решить данную проблему, любые варианты решения интересны, я перепробовал много, но самое лучшее, что у меня получилось этов три запроса.:nezn:
     
  2. BlackPawn

    BlackPawn Постоялец

    Регистр.:
    19 мар 2009
    Сообщения:
    75
    Симпатии:
    27
    То есть, вложенность разделов не больше 2?
     
  3. askarbin

    askarbin

    Регистр.:
    31 мар 2009
    Сообщения:
    292
    Симпатии:
    36
    Да, не больше двух. Разделы родительские и их подразделы.
     
  4. BlackPawn

    BlackPawn Постоялец

    Регистр.:
    19 мар 2009
    Сообщения:
    75
    Симпатии:
    27
    Код:
    select object.name, if(t1.parent=0, t1.name, t2.name) as parent
    from object 
      left join typeobject as t1 on object.type=t1.id
      left join typeobject as t2 on t1.parent=t2.id
    
    можно чуть короче
    Код:
    select object.name, ifnull(t2.name, t1.name) as parent
    from object 
      left join typeobject as t1 on object.type=t1.id
      left join typeobject as t2 on t1.parent=t2.id
    
     
    askarbin нравится это.
  5. Laba

    Laba Создатель

    Регистр.:
    27 сен 2009
    Сообщения:
    18
    Симпатии:
    2
    Может быть так?

    select a.*
    from typeobject a
    where a.parent = 0
    and exist (select 1 from typeobject b
    where a.id = b.parent
    and exist (select 8 from object
    where b.id = objects.type))
    or exist (select 8 from objects
    where a.id = objects.type)
     
  6. BlackPawn

    BlackPawn Постоялец

    Регистр.:
    19 мар 2009
    Сообщения:
    75
    Симпатии:
    27
    запрос не работает
    Код:
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select 1 from typeobject b where a.id = b.parent and exist (select 8 from object' at line 4
    
    К тому же, 3 подзапроса будут выполняться гораздо дольше, чем мой вариант.
     
  7. Laba

    Laba Создатель

    Регистр.:
    27 сен 2009
    Сообщения:
    18
    Симпатии:
    2
    Если исправить синтаксические ошибки и отформатировать, то будет выглядеть так (проверить не могу - базы под руокй нет:(

    SELECT a . *
    FROM typeobject a
    WHERE a.parent =0
    AND EXISTS (

    SELECT 1
    FROM typeobject b
    WHERE a.id = b.parent
    AND EXISTS (

    SELECT 8
    FROM objects
    WHERE b.id = objects.type
    )
    )
    OR EXISTS (

    SELECT 8
    FROM objects
    WHERE a.id = objects.type
    )

    2BlackPawn: наши запросы, я бы сказал, так сильно отличаются, что их сравнивать даже трудно - они решают разные задачи. Мой выводит просто список родительских разделов, а Ваш? :)
     
    askarbin нравится это.
  8. askarbin

    askarbin

    Регистр.:
    31 мар 2009
    Сообщения:
    292
    Симпатии:
    36
    Ваши запросы работают и работаю хорошо, только выборка идет не того, что мне нужно. Я настолько глубоко синтаксис mysql не знаю, поэтому запрос переделать мне очень тяжело. Задача то заключалась не в выборке всех объектов с их родительскими категориями, а в том, чтобы создать меню, которое будет состоять из родительских категорий для которых (или для дочерних объектов которых) в таблице objects есть объекты. Спасибо вам за помощь, синтаксис запроса от Laba остался мне непонятен вообще, чтобы его подогнать под мою БД. Я понимаю, что разжевывать мне никто не будет тут, ну все равно спасибо большое вам за помощь.

    А вообще подогнать запрос от Laba я тоже смог, он выглядит так для моей таблицы (если я конечно все правильно понял)
    SELECT a . *
    FROM typeobject a
    WHERE a.parent =0
    AND EXISTS (

    SELECT 1
    FROM typeobject b
    WHERE a.id_typeobject = b.parent
    AND EXISTS (

    SELECT 8
    FROM objects
    WHERE b.id_typeobject = objects.type
    )
    )
    OR EXISTS (

    SELECT 8
    FROM objects
    WHERE a.id_typeobject = objects.type
    )

    Но на выходе я просто получил всю таблицу typeobject, а не список родительских категорий. (* в запросе я изменил a.id и b.id на b.id_typeobject и b.id_typeobject соответственно, т.к. на сколько я понял это идентификаторы из таблицы typeobject, а у меня они заданы как id_typeobject)
     
  9. BlackPawn

    BlackPawn Постоялец

    Регистр.:
    19 мар 2009
    Сообщения:
    75
    Симпатии:
    27
    Вначале, не так поняла :)
    Код:
    select distinct ifnull(t2.name, t1.name) as parent
    from object 
      left join typeobject as t1 on object.type=t1.id
      left join typeobject as t2 on t1.parent=t2.id
    
     
    askarbin нравится это.
  10. Laba

    Laba Создатель

    Регистр.:
    27 сен 2009
    Сообщения:
    18
    Симпатии:
    2
    Мой запрос и последний запрос BlackPawn делают по-сути одно и тоже. Результат должен быть один и тот же.

    Если оба выводят все родительские разделы, то значит такие данные в таблицах.
     
Статус темы:
Закрыта.