Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Многотабличный запрос - отношение многие ко многим
 
 автор: SHAman   (24.07.2007 в 22:00)   письмо автору
 
 

Народ, помогите. Есть задачка:
Есть статьи в блог и теги. В каждой статье может быть несколько тегов. Реализовано отношение многие ко многим из трех таблиц. Структура:

states
=====
id
id_user
content


tags
====
id
name


states_tags
=========
id_tag
id_state

Дан id тэга и id юзера. Нужно вывести все статьи, принадлежащие этому пользователю, в которых есть этот тег.

Длеаю так:

SELECT
            'states.id', 'states.id_user', 'states.full', 'states.short', 'states.header',
            DATE_FORMAT('states.date', '%d.%m.%Y') AS 'date',
            'tags.id', 'tags.name',
            'states_tags.id_tag', 'states_tags.id_state'
        FROM
            `states`, `states_tags`, `tags`
        WHERE
            'tags.id' = $num AND
            'states_tags.id_tag' = 'tags.id' AND
            'states_tags.id_state' = 'states.id' AND
            'states.id_user' = $user[id]
        ORDER BY 'date'
        LIMIT $start_rec, $t_p_page

Ошибок не выводит, но и выборка нулевая. Помогите пожалуйста.

ЗЫ. Извините, что неотредактированный запрос кидаю, с лишними ячейками, просто спешу.

   
 
 автор: Trianon   (24.07.2007 в 22:15)   письмо автору
 
   для: SHAman   (24.07.2007 в 22:00)
 

У Вас все имена в апострофы взяты - и в результате Вы извлекаете и приравниваете текстовые строки.
'states_tags.id_tag' = 'tags.id' AND

   
 
 автор: Trianon   (24.07.2007 в 22:28)   письмо автору
 
   для: SHAman   (24.07.2007 в 22:00)
 

Если данных о тегах не требуется - вот такой вложенный запрос, по-моему - оптимален.

SELECT * FROM 
states 
WHERE 
   id_user = $user_id
  AND 
    id IN (SELECT id_state 
              FROM states_tags 
                WHERE id_tag = $num
          )
ORDER BY date
 LIMIT $start_rec, $t_p_page 


Если требуется - всяко лучше переписать через соединение.

   
 
 автор: oradev   (24.07.2007 в 23:20)   письмо автору
 
   для: Trianon   (24.07.2007 в 22:28)
 

Насчет оптимальности с Trianon поспорил бы!!!

select * from states s WHERE EXISTS (SELECT * FROM states_tag stg where s.id = stg.id_state AND stg.id_tag = $num)
and s.id_user = $id_user;



Но спорить бесполезно,увы!

   
 
 автор: Trianon   (25.07.2007 в 09:04)   письмо автору
 
   для: oradev   (24.07.2007 в 23:20)
 

Ну почему же бесполезно?

Мне довольно интересно будет узнать у специалиста, почему коррелированный запрос оптимальнее обыкновенного вложенного.

   
 
 автор: SHAman   (24.07.2007 в 23:21)   письмо автору
 
   для: Trianon   (24.07.2007 в 22:28)
 

С кавычками пока не разобрался. когда какие ставить. Обратные, на сколько я понял, нужно ставить, если обращаешься к ячейкам в базе. То есть, типа `id`. А прямые кавычки-апострофы, нужно когда подставляешь значения. Видимо, не до конца понял.

Запрос интересный, спасибо. Но он действительно не даст данных о тегах. Они нужны тоже. Подскажите, как это будет?

Ламерские вопросы, понимаю, но это не надолго. Я быстро учусь.

   
 
 автор: Trianon   (25.07.2007 в 09:12)   письмо автору
 
   для: SHAman   (24.07.2007 в 23:21)
 

В обратные косые кавычки (`бэктики`) заключаются имена таблиц и имена полей.
В "обычных кавычках" и 'апострофах' пишутся текстовые литералы, т.е. строки.



SELECT states.*, tags.* 
  FROM  
    states  
      JOIN states_tags ON states.id = states_tags.id_state 
      JOIN tags ON states_tags.id_tag = tags.id
  WHERE  
       id_user = $user_id 
    AND tags.id_tag=$num
 ORDER BY states.date 
 LIMIT $start_rec, $t_p_page  

   
 
 автор: oradev   (25.07.2007 в 11:26)   письмо автору
 
   для: Trianon   (25.07.2007 в 09:12)
 


SELECT st.id,st.id_user,t.name
FROM states_tags stg JOIN states st ON (stg.id_state = st.id)
JOIN tags t ON (stg.id_tag = t.id)
WHERE t.id = $num AND st.id_user = $user_id;

   
 
 автор: Trianon   (25.07.2007 в 11:47)   письмо автору
 
   для: oradev   (25.07.2007 в 11:26)
 

верно. Один join я посеял. :)
Поправил, впрочем.

   
 
 автор: Trianon   (25.07.2007 в 11:50)   письмо автору
 
   для: Trianon   (25.07.2007 в 09:12)
 

Голова садовая...

SHAman, Вы меня таки запутали.
Нет тут никакого соединения. Не нужны они при фиксированном tags.id = $num

Есть два независимых запроса.
Один

SELECT * FROM tags WHERE id = $num

Другой - тот, что я привел в (24.07.2007 в 22:28)

   
 
 автор: SHAman   (25.07.2007 в 12:34)   письмо автору
 
   для: Trianon   (25.07.2007 в 11:50)
 

Всем спасибо, попробую все, доложу о результате:) Эх.. знал, что SQL сложный язык... справочник есть, но не сильно помогает, когда не знаешь где смотреть. Надо cookbook купить.

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования