|
|
|
| Есть две таблицы. Таблица тем форма, и ответов.
Нужно вывести список тем + первый пост из этой темы. Есть ли у кого идеи как такое сделать без дополнительного и вложенного запроса? Как можно связать таблицы, но получить только одну запись из привязанной?
GROUP BY не предлагать! Так как нужен именно первый пост темы!
SELECT
`forum_topics`.`id`,
`forum_topics`.`title`,
`forum_topics`.`posts`,
`forum_topics`.`views`,
`forum_posts`.`post`
FROM
forum_topics
LEFT JOIN forum_posts ON forum_posts.topic_id = forum_topics.id
WHERE `forum_topics`.`open_user_id`=1
ORDER BY `forum_topics`.`start_date` DESC
|
| |
|
|
|
|
|
|
|
для: Diablo_
(03.04.2013 в 20:40)
| | А чем вам не угодил вложенный подзапрос?
Кореллирующий подойдет? | |
|
|
|
|
|
|
|
для: Diablo_
(03.04.2013 в 20:40)
| | Да,да. выдернуть одно поле из другой таблицы - коррелирующий запрос само то | |
|
|
|
|
|
|
|
для: Igorek
(04.04.2013 в 13:30)
| | .... в ожидании ответа топикстартера .....
=) | |
|
|
|
|
|
|
|
для: Igorek
(04.04.2013 в 13:30)
| | А чем он отличается от вложенного?) | |
|
|
|
|
|
|
|
для: Diablo_
(06.04.2013 в 14:20)
| | Коррелирующий - это частный случай вложенного. Такой запрос выполняется для каждой строки, которая может быть выбрана внешним запросом | |
|
|
|
|
|
|
|
для: Igorek
(08.04.2013 в 10:09)
| | А как он делается? О_о | |
|
|
|
|
|
|
|
для: Diablo_
(12.04.2013 в 00:42)
| | Обычный вложенный запрос, только в нем используются столбцы из внешнего запроса.
SELECT * FROM forum_topics
WHERE id IN (SELECT topic_id FROM forum_posts WHERE filed = forum_topics.some_filed)
|
PS Только у коррелирующих запросов есть минус - они выполняются для каждой строки внешнего запроса. | |
|
|
|
|
|
|
|
для: cheops
(12.04.2013 в 07:32)
| | > они выполняются для каждой строки внешнего запроса.
Ничего подобного. Оптимизатор от этого как-то избавляется.
Проверил на таком примере:
EXPLAIN
SELECT user
, (SELECT summ
FROM charge
WHERE user=c.user
ORDER BY rand( )
LIMIT 1)s
FROM `charge` c
| и вот результат:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
-----------------------------------------------------------------------------------------------------------------------------------
1 | PRIMARY | c | index | NULL | user_id | 152 | NULL | 11 | Using index
2 | DEPENDENT SUBQUERY | charge | ref | user_id | user_id | 152 | test.c.user | 2 | Using temporary; Using filesort
|
| |
|
|
|
|
|
|
|
для: Sfinks
(12.04.2013 в 08:24)
| | В SELECT да, а WHERE не должно бы такого быть. Причем заметьте, две записи, индекс (с отличным попаданием) - а ложатся все-равно на диск. | |
|
|
|
|
|
|
|
для: cheops
(13.04.2013 в 18:09)
| | > В SELECT да, а WHERE не должно бы такого быть.
Да вроде тоже все нормально:
EXPLAIN
SELECT *
FROM charge c
WHERE id IN(
SELECT id
FROM charge
WHERE user=c.user
)
| и даже без файлсорта:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
--------------------------------------------------------------------------------------------------------------------
1 | PRIMARY | c | ALL | NULL | NULL | NULL | NULL | 11 | Using where
2 | DEPENDENT SUBQUERY | charge | unique_subquery | PRIMARY,user_id | PRIMARY | 4 | func | 1 | Using where
|
> Причем заметьте, две записи, индекс (с отличным попаданием) - а ложатся все-равно на диск.
Это да.
В MySQL вообще нет очень много конструкций, облегчающих жизнь, приходится изворачиваться не самыми удачными способами. | |
|
|
|