Вопрос по SELECT с несколькими таблицами

Phristen

Новичок
Вопрос по SELECT с несколькими таблицами

Есть подобный запрос:

SELECT t1.*, COUNT(t2.c) AS t2c FROM t1, t2 WHERE t1.a=t2.b AND t1.d=1 GROUP BY t1.id

Если в колонке "b" таблицы t2 не находится значения, равного "a" из таблицы t1, то mysql возвращает пустой набор. (разумеется)
Вопрос: как сделать так, чтобы вместо пустого набора возвращался всё тот-же единственный ряд (где t1.d=1), но чтобы COUNT(t2.c) был равен нулю?
Единственное, что пришло в голову, это вот это:

(SELECT t1.*, COUNT(t2.c) AS t2c FROM t1, t2 WHERE t1.a=t2.b AND t1.d=1 GROUP BY t1.id)
UNION
(SELECT t1.*, 0 AS t2c FROM t1, t2 WHERE t1.d=1 GROUP BY t1.id)

Первая строка идентична начальному запросу.
Вторая - копия первой, но t2c заранее равно нулю, а условие t1.a=t2.b не проверяется.
Таким образом, первый ряд результата быдет всегда присутствовать. Но... Что, если сравнение будет происходить не между двумя таблицами, а между десятью? Не делать же 10^2 селектов на все случаи жизни?

P.S. Извиняюсь за возможно запутанное объяснение :(
 

zerkms

TDD infected
Команда форума
[sql]
SELECT t1.*, COUNT(`t2`.`b`) FROM `t1` LEFT JOIN `t2` ON `t1`.`a` = `t2`.`b` WHERE `t1`.`d` = 1 GROUP BY `t1`.`id`
[/sql]
 

Phristen

Новичок
Автор оригинала: zerkms
[sql]
SELECT t1.*, COUNT(`t2`.`b`) FROM `t1` LEFT JOIN `t2` ON `t1`.`a` = `t2`.`b` WHERE `t1`.`d` = 1 GROUP BY `t1`.`id`
[/sql]
Спасибо. Работает с двумя таблицами, но с тремя - уже нет. COUNT оба раза насчитывает больше чем нужно:
[sql]SELECT a.*, COUNT(b.a) AS ba, COUNT(c.a) AS ca FROM a
LEFT JOIN b ON b.a=a.a
LEFT JOIN c ON c.b=a.b
WHERE a.id=3
GROUP BY a.id[/sql]

P.S. Спасает слово DISTINCT. Т.е., например, COUNT (DISTINCT ...) А по-другому никак?

-~{}~ 04.11.06 06:37:

И ещё одна загвоздка. Если последний запрос в-общем-то рабоатет, то когда убираю условие where, mysql виснет. Неужели два джойна это такая невыполнимая нагрузка, если в таблицх всего по 1-10 тысяч записей?
 

Phristen

Новичок
Автор оригинала: alpine
Phristen
Покажи EXPLAIN своих запросов.
explain запроса с ограничением where
PHP:
table  	 type  	 possible_keys  	 key  	 key_len  	 ref  	 rows  	 Extra
u 	 	ref  	 		id 	 	id  		4 	 	const 	1 	Using where
c 	 	ALL   			NULL 	 	NULL 	NULL  		NULL 	16 	 
a  		ALL  	 		NULL  		NULL 	NULL  		NULL 	12299
без ограничения
PHP:
 table  	 type  	 possible_keys  	 key  	 key_len  	 ref  	 rows  	 Extra
u  		ALL  	 		NULL 	 	 NULL 	NULL  		NULL 	1031 	Using temporary; Using filesort
c  		ALL  	 		NULL 	  	NULL 	NULL  		NULL 	16 	 
a  		ALL  	 		NULL 	  	NULL 	NULL  		NULL 	12299
 

alpine

Новичок
Phristen
Покажи структуру таблиц и реальные(не выдуманные здесь для примера) запросы.
 

Phristen

Новичок
Автор оригинала: alpine
Phristen
Покажи структуру таблиц и реальные(не выдуманные здесь для примера) запросы.
Запрос нужен для отображения юзеров. Берутся имя, место проживания, дата регистрации и кол-во комментариев. (берётся из других таблиц, которые и присоединяются джойном)

[sql]SELECT u.id, u.name, u.city, DATE_FORMAT(u.reg, '%M %D, %Y') AS reg, COUNT(DISTINCT c.id) AS coms, COUNT(DISTINCT a.id) AS arts FROM usr AS u LEFT JOIN com AS c ON c.user = u.id LEFT JOIN art AS a ON a.user=u.id GROUP BY u.id LIMIT $offset, $users_per_page[/sql]

Таблицы:
art
----
id int(11) unsigned PRI NULL auto_increment
user int(11) 0
cat int(11) 0
body text
title tinytext
created datetime 0000-00-00 00:00:00
modif datetime 0000-00-00 00:00:00
visible int(11) 0

usr
----
Field Type Null Key Default Extra
id int(11) unsigned PRI NULL auto_increment
login tinytext
name tinytext
city tinytext
reg datetime 0000-00-00 00:00:00
lvl int(11) 0
mail tinytext
pass tinytext
bio text

com
----
id int(11) unsigned PRI 0
user int(11) 0
art int(11) 0
posted datetime 0000-00-00 00:00:00
title tinytext
body text
 

alpine

Новичок
Phristen
Индексы есть для полей которые учавствуют в объединении таблиц?
 

Phristen

Новичок
Нет, индексов нет (за исключением u.id, где id - primary key). Создать?
 

alpine

Новичок
moxnatiy
Возможно.

-~{}~ 04.11.06 23:00:

Phristen
Обязательно.

-~{}~ 04.11.06 23:01:

После создания индексов посмотри EXPLAIN. Имхо время выполнения уменьшится.
 

Phristen

Новичок
А ведь заработало!
Премного благодарю! :)

P.S. Новый explain выглядит так:
PHP:
table  	 type  	 possible_keys  	 key  	 key_len  	 ref  	 rows  	 Extra
u  		ALL 	 	 	 	NULL 	NULL 	NULL  		NULL 	1031 	Using temporary; Using filesort
c  		ALL  	 	 		user 	NULL 	NULL  		NULL 	12 	 
a  		ref  	 	 		user 	user 	4   			u.id 	12
 
Сверху