MySQL - запрос (статистика)
В результате хочется получить сведения о строках первой таблицы и количестве строк второй таблицы, соответствующих каждой из них, включая те, у которых нет подчиненных (0). Для этого написал такой запрос:
(SELECT DISTINCT tab1.*, 0 AS kol FROM tab1, tab2 WHERE tab2.tab1id<>tab1.id)
UNION
(SELECT tab1.*, COUNT(*) AS kol FROM tab1, tab2 WHERE tab2.tab1id=tab1.id GROUP BY id) ORDER BY id
Вторая часть селекта работает как надо, т.е. считает и выдает количество подчиненных строк, привязанное к строкам первой таблицы, а вот первая часть селекта выдает набор из всех строк первой таблицы и нуля вместо количества. А надо, чтобы выдавала только те строки tab1, которым нет соответствия в tab2. В чем ошибка и как, если можно, сделать тоже самое по другому?
Цитата:
Originally posted by Rey
В чем ошибка и как, если можно, сделать тоже самое по другому?
В чем ошибка и как, если можно, сделать тоже самое по другому?
Через внешнее объединение. Ищи по форуму по ключевым словам "left join", вопрос уже неоднократно поднимался.
SELECT DISTINCT tab1.*, 0 AS kol FROM tab1, tab2 WHERE tab2.tab1id<>tab1.id
выдает всю tab1? С "left join" я тоже пробовал, кстати. Я хочу сначала понять, в чем я не прав, а уж потом - как сделать правильно.
Цитата:
Originally posted by Rey
Спасибо за совет в стиле RTFM. Только меня интересует, ПОЧЕМУ выражение
SELECT DISTINCT tab1.*, 0 AS kol FROM tab1, tab2 WHERE tab2.tab1id<>tab1.id
Спасибо за совет в стиле RTFM. Только меня интересует, ПОЧЕМУ выражение
SELECT DISTINCT tab1.*, 0 AS kol FROM tab1, tab2 WHERE tab2.tab1id<>tab1.id
В SQL действует логика работы с множествами при обработке операторов сравнения. Раз у тебя заданы два поля из разных таблиц, результат представляет зеркальный вариант отношения "равно", т. е. все комбинации, не попадающие под категорию "равно". В твоем примере это фактически декартово произведение всех строк, за исключением одной (равной).
Если нужно сравнить значение поля не с константой и не получить при этом картезианский продукт, пишут:
Код:
not tab1.id = tab2.id
SELECT DISTINCT tab1.*, 0 AS kol FROM tab1, tab2 WHERE NOT (tab2.tab1id = tab1.id)
выдала опять список из всех строк первой таблицы, а без скобок не выдала ничего :(
Я понимаю, что ничего не понимаю...
SELECT tab1.*, 0 AS kol FROM tab1 LEFT JOIN tab2 ON tab1.id=tab2.tab1id WHERE tab2.tab1id IS NULL
Спасибо всем за помощь!