Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: COUNT и GROUP BY
 
 автор: tAleks   (31.01.2007 в 18:02)   письмо автору
 
 

Есть такой запрос:

SELECT sections.*, COUNT(sec.id_section) AS col, COUNT(blocks.id_block) AS blocks
        FROM sections 
            LEFT JOIN sections AS sec ON sections.id_section = sec.pid_section
            LEFT JOIN sections_blocks_select AS blocks ON sections.id_section = blocks.id_section
        WHERE sections.id_part = ".$id_part." AND sections.pid_section = 0
        GROUP BY sections.id_section
        ORDER BY sections.pos


В результирующей таблице нужно получить два COUNT посчитанных из др. таблиц. Но получается что значения col и blocks перемножены друг на друга...

Если один COUNT убрать то все работает нормалаьно... а если два... то их хначения перемножаются друг на друга. Причем только тогда когда второй COUNT больше 1.

Вопрос:
Как составить правильно такой запрос?

   
 
 автор: Trianon   (31.01.2007 в 18:44)   письмо автору
 
   для: tAleks   (31.01.2007 в 18:02)
 

Как составить правильно такой запрос?

Выбираемые оператором SELECT поля всегда принадлежат ОДНОЙ (возможно - совокупной) таблице. Отсюда результат, который Вы имеете.
Хотите независимо выбирать данные разных таблиц - выбирайте их РАЗНЫМИ SELECTами.
Хотите получить эти данные одним запросом - объединяйте РАЗНЫЕ SELECTы в один UNION - в простых случаях, или общим SELECt JOIN-ом - в сложных.

   
 
 автор: tAleks   (31.01.2007 в 21:03)   письмо автору
 
   для: Trianon   (31.01.2007 в 18:44)
 

>Выбираемые оператором SELECT поля всегда принадлежат ОДНОЙ (возможно - совокупной) таблице. Отсюда результат, который Вы имеете.

Не понял я как это связано с резульататом...

запрос с одним COUNT и одним JOIN работает нормально, т.е. COUNT считает то что нужно:

SELECT
        sections.*, 
        COUNT(sec.id_section) AS col
        FROM sections 
        LEFT JOIN sections AS sec ON sections.id_section = sec.pid_section
        WHERE sections.id_part = ".$id_part." AND sections.pid_section = 0
        GROUP BY sections.id_section
        ORDER BY sections.pos


>Хотите независимо выбирать данные разных таблиц - выбирайте их РАЗНЫМИ SELECTами.
>Хотите получить эти данные одним запросом - объединяйте РАЗНЫЕ SELECTы в один UNION - в простых случаях, или общим SELECt JOIN-ом - в сложных.


Так я и объединяю таблицы JOIN-ом.

У меня 2 таблицы:
- в одной храняться пункты меню
- в другой блоки (отображаемые в разеделе (пункте))

Я извлекаю пункты меню, JOINом прибавляю таблицу (эту же, но с другим именем) и первым COUNTом считаю кол-во подпунктов в пункте.

А вторым JOINом я прибавляю таблицу с блоками и вторым COUNTом считаю кол-во блоков в пункте.

Вот в принципи, что мне и надо-то...

Где я тока накосячил? Так и не могу врубиться....

Помогите, плиз...

   
 
 автор: Trianon   (31.01.2007 в 21:21)   письмо автору
 
   для: tAleks   (31.01.2007 в 21:03)
 

Смотрите внимательно за руками:
это один счет

SELECT ref1, count(ref1) FROM tab1 GROUP by ref1

это второй счет

SELECT ref2, count(ref2) FROM tab2 GROUP by ref2 



>>объединяйте РАЗНЫЕ SELECTы
>Так я и объединяю таблицы JOIN-ом.
Так я и говорю что Вы соединяете не то что надо.
Вы соединяете именно таблицы:


SELECT ref1, count(tab1.ref1) , count(tab2.ref2) 
  FROM tab1 
  LEFT JOIN tab2 ON ref1=ref2 GROUP BY ref1


А надо соединять селекты отдельных счетов:

SELECT ref1, ct1, ct2 
  FROM 
        (SELECT ref1, count(ref1) as ct1 FROM tab1 GROUP by ref1)as sel1 
    LEFT JOIN 
        (SELECT ref2, count(ref2) as ct2  FROM tab2 GROUP by ref2 )as sel2
    ON ref1=ref2

   
 
 автор: tAleks   (31.01.2007 в 21:25)   письмо автору
 
   для: Trianon   (31.01.2007 в 21:21)
 

ОК. Сейчас попробую так....

Но почему тогда, при ОДНОМ объединении (как я делал) и одном счете (см. запрос выше) все работает нормально?

Может COUNTы меж собой конфликтуют в одной таблице? Нет?

   
 
 автор: Trianon   (31.01.2007 в 21:32)   письмо автору
 
   для: tAleks   (31.01.2007 в 21:25)
 

>Но почему тогда, при ОДНОМ объединении (как я делал) и одном счете (см. запрос выше) все работает нормально?

1. При одном соединении. JOIN - соединение, (т.е. построчное перемножение таблиц, отсюда и перемножение числа строк) а не объединение( UNION, т.е. слияние двух в одну) .
2. Как выглядит запрос, который работает "нормально"?
С моей точки зрения, нормальная работа - та самая, которую Вы и описали.

   
 
 автор: tAleks   (31.01.2007 в 21:40)   письмо автору
 
   для: Trianon   (31.01.2007 в 21:32)
 

>2. Как выглядит запрос, который работает "нормально"?

Ну вот этот:

SELECT 
        sections.*,  
        COUNT(sec.id_section) AS col 
        FROM sections  
        LEFT JOIN sections AS sec ON sections.id_section = sec.pid_section 
        WHERE sections.id_part = ".$id_part." AND sections.pid_section = 0 
        GROUP BY sections.id_section 
        ORDER BY sections.pos 



он у меня работал нормально. Колонка col считала сумму подгрупп в каждой группе. (правильно считала).

Работал до тех пор, пока я не решил что еще в одном столбце таблицы надо показывать сумму блоков в каждом разделе, и не прибавил второй COUNT и второй JOIN.

Я то как думаю... может я че-то конечно не правильно думаю... но так:
JOINами я делаю одну таблицу из трех. Т,е. столбыц одной таблицы прибавляю к столбцам другой таблицы. и получается одна широкая (с многими столчиками) таблица.... а потом, как с обычной одинарной таблицей с ней можно делать все что угодно...

   
 
 автор: Trianon   (31.01.2007 в 21:52)   письмо автору
 
   для: tAleks   (31.01.2007 в 21:40)
 

Так у Вас же здесь один LEFT JOIN ?
Вся масса строк - произведение масс двух таблиц.

А в том запросе, который Вы хотите, два LEFT JOIN - произведение масс трех таблиц.
а группировка всего по одному полю.

   
 
 автор: Trianon   (31.01.2007 в 21:55)   письмо автору
 
   для: tAleks   (31.01.2007 в 21:40)
 

ЕЩЕ РАЗ!
JOIN не только добавляет столбцы.
JOIN в первую очередь перемножает строки!

   
 
 автор: tAleks   (31.01.2007 в 22:07)   письмо автору
 
   для: Trianon   (31.01.2007 в 21:55)
 

>JOIN в первую очередь перемножает строки!

Как перемножает? Скока читал, не видел такого... дайте ссылку, где написано....

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования