2012-06-01 2 views
1

В моей базе данных у меня есть две таблицы: ответы и темы.Объединение двух запросов MySQL в один

Я пытаюсь создать страницу Contributions, показывающую, к каким потокам пользователи начали или ответили.

Внутренние ответы - это «ThreadId» и «Poster», которые определяют идентификатор потока, на который он был дан ответ, и каждая строка в Threads имеет столбец Id, а также столбец «Poster». .

Я пытаюсь сделать запрос, чтобы получить ряды всех НИТЕЙ, в котором пользователь либо размещены или размещены в

Пример:

$myUsername = "Bob"; 
$q = mysql_query("SELECT * FROM `Threads` WHERE `Poster`='$myUsername' 
OR (another query to find if they had a row in Replies matching `ThreadId`='$tid' 
AND `Poster`='$myUsername')"); 

Благодаря

+0

сообщение SHOW CREATE TABLE Темы и SHOW CREATE TABLE Ответы – rkosegi

+0

Соединение слева Плакат с потоками. – Panagiotis

+1

опубликуйте свою структуру на http://sqlfiddle.com/, и мы будем рады ответить –

ответ

0

Вы будете необходимо использовать предложение IN, чтобы указать, что идентификатор потока должен находиться в возвращаемых запросом в таблице ответов. Что-то вроде этого я правильно понимаю структуру ваших таблиц.

SELECT * FROM Threads WHERE Poster = $myUsername OR Id IN (
SELECT ThreadId FROM Replies WHERE Poster = $myUsername 
) 
+0

. Этот запрос занимает очень много времени для загрузки и использования большого количества CPU.У меня более 10 000 строк в Threads и 100 000 строк в Replies. Это запрос или мой db? – Anonymous

+0

У вас есть необходимые индексы для ускорения выполнения запроса? Вы можете видеть, какие части запроса занимают больше всего времени? – Christina

+0

Я не знаю, как увидеть, какие части занимают больше всего времени, но я попытался заменить «SELECT * FROM» на просто «SELECT' Id' FROM », который является индексом строк, и он по-прежнему медленно загружается. – Anonymous

0

Использование решения Christina, вероятно, не приведет к очень эффективному запросу. Следующий должен быть лучше:

SELECT * 
FROM Threads t1 
WHERE t1.Poster='$myUsername' 
UNION 
SELECT * 
FROM Threads t2 
INNER JOIN replies r 
ON t2.id=r.thread_id 
WHERE t2.Poster<>'$myUsername' 
AND r.Poster='$myUsername'; 

Однако:

1) вам действительно нужно все столбцы из таблицы threas? Даже если вы делаете, используя «*» грязен

2) вы все еще собираетесь получить дубликаты, если пользователь сделал еще более одного ответа - но это не может быть исправлено при использовании «*»

3) запрос будет по-прежнему медленным и большим количеством данных, если у вас нет индекса на плакате в обеих таблицах.

0

Я сделал это по-другому. Два запроса предоставили дубликаты, а что нет, поэтому я решил пойти немного дольше.

Что я сделал:

1) Переход через каждый из ответов пользователя, и получить идентификатор потока

2) Построить строку запроса с использованием этих идентификаторов, например, "ИЛИ Id = $ ThreadId ИЛИ Id = $ threadId2" и т.д.

3) Поместите строку запроса в запросе нити, такие как SELECT * FROM резьбе там, где плакат = $ $ queryString2 пользователя

4) Решение. :)

0

Попробуйте это:

Вы можете использовать LEFT OUTER JOIN вместо В оператора

SELECT T.* 
FROM Threads T 
LEFT OUTER JOIN Replies R ON T.Id = R.ThreadId AND R.Poster = $myUsername 
WHERE T.Poster = $myUsername OR R.Id IS NOT NULL