2010-03-22 3 views
2

Код ниже отлично работает. Он объединяет данные из двух таблиц MySQL. Я хотел бы изменить его, потянув некоторые данные из третьей таблицы MySQL, которая называется comment.Использование соединения с тремя таблицами, когда поле может быть пустым

В таблице ниже, title - это поле в таблице MySQL submission. Каждый title имеет соответствующее поле submissionid. Поле submissionid также найдено в таблице MySQL comment.

В HTML таблицы ниже, я хотел бы countComments равным число раз поле под названием commentid появляется в таблице MySQL comment для любого заданного submissionid, где submissionid одинакова в обеих таблицах submission и comment, и где submissionid соответствует используемому title.

Вот улов: если нет строки в таблице MySQL comment, который соответствует submissionid используется для table, я хотел бы countComments равным нулю.

Как я могу это сделать?

$sqlStr = "SELECT s.loginid, s.title, s.url, s.displayurl, l.username 
      FROM submission AS s, 
        login AS l 
      WHERE s.loginid = l.loginid 
     ORDER BY s.datesubmitted DESC 
      LIMIT 10"; 


$result = mysql_query($sqlStr); 

$arr = array(); 
echo "<table class=\"samplesrec\">"; 
while ($row = mysql_fetch_array($result)) { 
    echo '<tr>'; 
    echo '<td class="sitename1"><a href="http://www.'.$row["url"].'">'.$row["title"].'</a></td>'; 
    echo '</tr>'; 
    echo '<tr>'; 
    echo '<td class="sitename2"><a href="http://www...com/sandbox/members/index.php?profile='.$row["username"].'">'.$row["username"].'</a><a href="http://www...com/sandbox/comments/index.php?submission='.$row["title"].'">'.$row["countComments"].'</a></td>'; 
    echo '</tr>'; 
    } 
echo "</table>"; 
+0

Каково точное имя поля uploadid в таблицах представления и комментариев? – Unreason

ответ

0

Если я правильно понял ваш вопрос правильно, как насчет:

SELECT s.loginid, s.title, s.url, s.displayurl, l.username, COUNT(c.id) AS commentCount 
FROM submission AS s 
LEFT JOIN login AS l ON l.loginid = s.loginid 
LEFT JOIN comments AS c ON c.submissionid = s.id 
ORDER BY s.datesubmitted DESC 
LIMIT 10 
+0

Хм ... Я попробовал, но все идет не так. Как будто запрос не имеет результатов. – John

+0

Вы должны изменить его, чтобы поля были правильными. Например, я написал COUNT (c.id), но я понятия не имею, как вызывается первичный ключ таблицы комментариев. Просто убедитесь, что все имена полей/таблиц верны, прежде чем запускать его. Кроме того, убедитесь, что вы читаете ошибки из базы данных для получения дополнительных подсказок. – webbiedave

+0

Спасибо ... Я убедился, что поля правильные. – John

1

Вы делаете внутреннее соединение, но вам необходимо внешнее соединение, в частности, LEFT JOIN. При LEFT JOIN таблица «слева» всегда соединяется, и если нет соответствия, поля таблицы справа имеют значение null. Эта разница очень хорошо объясняется в этом wikipedia page.

Затем вам нужно сгруппировать строки с одним и тем же идентификатором отправки и подсчитать, сколько строк было сгруппировано, если у вас есть только один комментарий, а у другого нет одной группы сгруппированы ... Если один представления не имеет ни одного комментария, в следующем запросе c.submissionid будет нулевым, так

Ваш SQL может быть

SELECT s.loginid, s.title, s.url, s.displayurl, l.username, c.submissionid, 
IF(c.submissionid IS NULL, 0, COUNT(*)) AS countComments 
FROM submission AS s 
INNER JOIN login AS l ON l.loginid = s.loginid 
LEFT JOIN comments AS c ON c.submissionid = s.id 
GROUP BY (s.id) 
ORDER BY s.datesubmitted DESC 
LIMIT 10 

Там могут быть ошибки, я не проверял запрос ... Но я надеюсь, что дал вы правильная идея, то есть разница между внешними соединениями и внутренними соединениями.

+0

Две вещи - после того, как вы используете группу, вы должны либо включать в себя оставшиеся поля под группой, либо использовать на них агрегатные функции (макс, мин, avg, сумма, счет и т. Д.) В то же время, если правильно выбрать написано, что это не понадобится. См. Здесь http://stackoverflow.com/questions/2496066/using-a-join-with-three-tables-when-a-field-might-be-null/2496406#2496406 – Unreason

+1

Я сделал тест и все работает как ожидалось ... Если s.id уникален для каждого представления (например, это первичный индекс), вам не нужно группировать по другим полям –

+1

+1 в комментарии к примечанию, которое не нужно группировать или группировать в mysql (не знал этого); с другой стороны - мои тесты показывают, что вы можете сбросить IF (c.submissionid IS NULL, 0, COUNT (*)) и заменить его на COUNT (c.submissionid) (ключевая часть - указать столбец, начинающийся с левого соединения , в противном случае ЕСЛИ НЕОБХОДИМО) – Unreason

0

попробовать

SELECT s.loginid, s.title, s.url, s.displayurl, l.username, c.submissionid, 
     COUNT(c.submissionid) AS countComments 
FROM submission AS s 
INNER JOIN login AS l ON l.loginid = s.loginid 
LEFT JOIN comments AS c ON c.submissionid = s.id 
GROUP BY s.loginid, s.title, s.url, s.displayurl, l.username, c.submissionid 
ORDER BY s.datesubmitted DESC 
LIMIT 10 

или

SELECT s.loginid, s.title, s.url, s.displayurl, l.username, c.submissionid, 
     (SELECT count(*) FROM submission s WHERE c.submissionid =s.submissionid) AS countComments 
FROM submission AS s 
INNER JOIN login AS l ON l.loginid = s.loginid 
ORDER BY s.datesubmitted DESC 
LIMIT 10 

обеспечение я не делал (м) опечаток :)

Если он работает для вас, я могу предоставить больше объяснений.

+0

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

+0

Вы получаете пробелы в php? Почему бы вам не запустить запрос непосредственно в mysql, чтобы увидеть точное сообщение об ошибке SQL, это поможет :) – Unreason

Смежные вопросы