count с использованием left join

UserAleks

Новичок
count с использованием left join

Не могу сообразить, как правильно составить запрос count.

Основная таблица с фирмами - `sto_firma`
CREATE TABLE `sto_firma`
(`firm_id` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11),

Есть 2 таблицы в которых храним информацию по марке и услугам
CREATE TABLE `sto_makes_firma`
(`mf_id` INT(11) NOT NULL AUTO_INCREMENT,
`firm_id` INT(11),

И
CREATE TABLE `sto_uslugi_firma`
(`tf_id` INT(11) NOT NULL AUTO_INCREMENT,
`firm_id` INT(11),

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

Вот примерный селект.
SELECT t1.firm_id
FROM `sto_firma` as t1
left join sto_makes_firma as t2 on t1.firm_id = t2.firm_id
left join array_makes as t22 on t2.makes_name = t22.makes_name
left join sto_uslugi_firma as t3 on t1.firm_id = t3.firm_id
left join sto_uslugi t33 on t3.us_id = t33.us_id
WHERE
t1.firm_open='1'
AND t1.sity_zip='90008'
AND ( t2.makes_name='audi' OR t2.makes_name='bmw' )
AND ( t3.us_id='5' OR t3.us_id='8' )
GROUP BY t1.firm_id LIMIT 0,15 ;


Селект осуществляем по 3-ом таблицам, основной и 2-ум зависящим. Тут все ок!

А вот подсчитать сколько фирм не могу. Уже даже не знаю что делать.
Вот примерный селект. Подскажите как или где ошибка.
SELECT t1.firm_id ,COUNT(*)
FROM `sto_firma` as t1
left join sto_makes_firma as t2 on t1.firm_id = t2.firm_id
left join sto_uslugi_firma as t3 on t1.firm_id = t3.firm_id
WHERE
t1.firm_open='1'
AND t1.sity_zip='90008'
AND ( t2.makes_name='audi' OR t2.makes_name='bmw' )
AND ( t3.us_id='5' OR t3.us_id='8'


При таком результате мне выдается на каждый t1.firm_id – сколько совпадений из left join по условию а мне это как бы не очень интересно важнее знать сколько фирм удовлетворяют условию.

Точнее мне нужен результат count(t1.firm_id).
 

Bitterman

Новичок
Правильно ли я понял, что, проще говоря, тебя интересует сколько строк вернет тебе твой запрос? Если да, то запрос должен быть: SELECT COUNT(*) FROM ... дальше, как и было. Если нужно и число строк и сам рекордсет, то mysql_num_rows.
 

UserAleks

Новичок
нужная информация у меня получаеться только через mysql_num_rows.
Самже count() мне возращяет сумму чисел совпадений из join на каждый t1.firm_id. ( тоесть в первом join совпадение 1 а вовтором два то результат будет
count():
t1.firm_id=3( 1 (1-ый join) + 2 (2-ой join) )
t1.firm_id=2( 1 (1-ый join) + 1 (2-ой join) )
... и т.п. на каждый t1.firm_id
а мне нжно сделать подсчет фирм по табл. sto_firma ).
Вот у меня и вопрос можно получить count() фирм запросом не используя mysql_num_rows
 

Trianon

Новичок
Если бы вы не писали GROUP BY к месту и не к месту, то SELECT COUNT(*) FROM ... заработал бы замечательно.
 

UserAleks

Новичок
У меня сейчас в базе есть 3 фирмы каждая фирма занимается определенной маркой и определенным видом услуг (марки и услуги записаны в другие таблицы – все это определяем по id фирмы) мне нужно узнать сколько фирм отвечают запросу.
В примере должно вывести 2 фирмы – это факт!

Вот варианты и результаты:
------
SELECT COUNT(*)…
Результат:
COUNT(*) |
3 |
Rows: 1 (исправил с 2 на 1)
-------
SELECT COUNT(*) … group by t1.firm_id;
для примера чтоб было понятно (результат селектов одинаков):
SELECT t1.firm_id,COUNT(*) … group by t1.firm_id;
Результ:
firm_id | COUNT(*)
52 | 2 – (проверил по join 1и2 найдены 2 совпадения)
53 | 1
Rows: 2
----------

-~{}~ 07.05.07 16:44:

Автор оригинала: Trianon
Если бы вы не писали GROUP BY к месту и не к месту, то SELECT COUNT(*) FROM ... заработал бы замечательно.
- ?
лучше подскажи, что толковое в чем загвозка.
*****************
сейчас попробовал сократить условие
...
AND ( t2.makes_name='audi' OR t2.makes_name='bmw' )
AND ( t3.us_id='5' OR t3.us_id='8' )
...
на
...
AND ( t2.makes_name='audi' )
AND ( t3.us_id='5' )
...
все вроде работает
не ужели вся загвозка в " OR " ?
 

Bitterman

Новичок
Первый запрос полностью приведи. Второй, заодно, тоже. А то у тебя получается, что первый запрос возвращает 2 фирмы, а второй, при тех же условиях, - 3. Чудес не бывает.
 

UserAleks

Новичок
SELECT COUNT(*)
FROM `sto_firma` as t1
left join sto_makes_firma as t2 on t1.firm_id = t2.firm_id
left join sto_uslugi_firma as t3 on t1.firm_id = t3.firm_id
WHERE
t1.firm_open='1'
AND t1.sity_zip='90008'
AND ( t2.makes_name='audi' OR t2.makes_name='bmw' )
AND ( t3.us_id='5' OR t3.us_id='8');
результ:
COUNT(*)
3
...
rows 1
**********
SELECT COUNT(*)
FROM `sto_firma` as t1
left join sto_makes_firma as t2 on t1.firm_id = t2.firm_id
left join sto_uslugi_firma as t3 on t1.firm_id = t3.firm_id
WHERE
t1.firm_open='1'
AND t1.sity_zip='90008'
AND ( t2.makes_name='audi' OR t2.makes_name='bmw' )
AND ( t3.us_id='5' OR t3.us_id='8') group by t1.firm_id;
результ:
COUNT(*)
2
1
...
rows 2
 

UserAleks

Новичок
в ручную проверил удовлетворяет условию только 2 фирмы
3 фирма не удовлетворяет ни одному из условий
точно!!!
я ее сейчас вобще грохнул.
осталось 2 фирмы - результат тотже
 

Bitterman

Новичок
То есть оба запроса работают неправильно?
Убери все COUNT и выведи список, посмотри, какие фирмы у тебя действительно удовлетворяют условию. Если ты прав, то, скорее всего, одна из фирм у тебя дублируется.
 

UserAleks

Новичок
DISTINCT-вроде уникальная запись?

SELECT t1.firm_id ,COUNT(DISTINCT t1.firm_id)
FROM `sto_firma` as t1
left join sto_makes_firma as t2 on t1.firm_id = t2.firm_id
left join sto_uslugi_firma as t3 on t1.firm_id = t3.firm_id
WHERE
t1.firm_open='1'
AND t1.sity_zip='3272'
AND ( t2.makes_name='audi' OR t2.makes_name='bmw' )
AND ( t3.us_id='5' OR t3.us_id='8') group by t1.firm_id;
результат
t1.firm_id | COUNT(DISTINCT t1.firm_id)
53 | 1
54 | 1
.....
rows 2
 

UserAleks

Новичок
Решена? да чет не знаю.
через DISTINCT он все равно выводит массив значений
перечесляя все поля в которых совпал.
а единного count со значением совпадений нет.
........
я проверил селект все впорядке.
Bitterman - Что ты имел ввиду "дублируеться" я сейчас тестирую и в базе всего 2 фирмы, дублирования нет.
 

chira

Новичок
UserAleks

если используешь LEFT JOIN у тебя как минимум будет весь список ID фирм с количеством 1
попробуй другой SQL
Код:
SELECT t1.firm_id, count(DISTINCT t1.firm_id)
FROM `sto_firma` as t1
left join sto_makes_firma as t2 on t1.firm_id = t2.firm_id AND ( t2.makes_name='audi' OR t2.makes_name='bmw' )
left join array_makes as t22 on t2.makes_name = t22.makes_name
left join sto_uslugi_firma as t3 on t1.firm_id = t3.firm_id
 AND ( t3.us_id='5' OR t3.us_id='8' )
left join sto_uslugi t33 on t3.us_id = t33.us_id
WHERE
t1.firm_open='1'
AND t1.sity_zip='90008'
GROUP BY t1.firm_id LIMIT 0,15 ;
 

chira

Новичок
UserAleks

значит нет ни одной фирмы с данными
t1.firm_open='1'
AND t1.sity_zip='90008'

-~{}~ 07.05.07 16:52:

ты заметил чем мой SQL от твоего в первом посте отличается?
 

UserAleks

Новичок
Автор оригинала: chira
UserAleks

значит нет ни одной фирмы с данными
t1.firm_open='1'
AND t1.sity_zip='90008'
;) - запарился, действительно нет
но вопрос открытый
результат в масиве значений
t1.firm_id | COUNT(DISTINCT t1.firm_id)
53 | 1
54 | 1
....
 

chira

Новичок
UserAleks
а какой ждёшь?

-~{}~ 07.05.07 17:01:

словами можешь описать условия выборки?

-~{}~ 07.05.07 17:03:

ещё предположение
Код:
SELECT t1.firm_id ,COUNT(DISTINCT t1.firm_id)
FROM `sto_firma` as t1
INNER join sto_makes_firma as t2 on t1.firm_id = t2.firm_id AND ( t2.makes_name='audi' OR t2.makes_name='bmw' )
INNER join sto_uslugi_firma as t3 on t1.firm_id = t3.firm_id AND ( t3.us_id='5' OR t3.us_id='8') group by t1.firm_id
WHERE
t1.firm_open='1'
AND t1.sity_zip='3272'
попробовать с INNER и LEFT JOIN
 
Сверху