Сложный запрос и Непредсказуемый результат (проблема с MySQL)

Jops
Дата: 28.01.2013 14:18:28
Здравствуйте Уважаемые!

Есть интересный запрос, который не даёт мне покоя уже неделю:

SELECT
                cg.group_id ,
                cg .group_name ,
                crg.cam_id ,
                crg.rule_status,
                SUM(IF(crg.rule_status = 0, cnt, 0)) as res_dlw,
                SUM(IF(crg.rule_status = 1, cnt, 0)) as res_alw,
                SUM(IF(crg.rule_status = 2, cnt, 0)) as res_ono
            FROM cams_rules_groups\
                RIGHT OUTER JOIN 
                    cams_groups as cg
                ON crg.group_id = cg.group_id
                    LEFT OUTER JOIN  (
                        SELECT
                            crg.group_id ,
                            crg.rule_status,
                            COUNT(*) as cnt
                        FROM
                            cams_rules_groups as crg
                        GROUP BY crg.group_id , crg.rule_status
                    ) as crg ON crgg.group_id = crg.group_id
            GROUP BY    cg.group_id


Смысл вот в чём. Есть две таблицы: cams_groups (group_id, group_name) ; cams_rules_groups (group_id, cam_id, rule_status).

group_id - ID группы , group_name - Имя группы / group_id - ID группы (дублируется из таблицы cams_groups ), cam_id - цыфры (могут быть повторяющимися), rule_status - цыфры (значения только 0, 1, 2 или res_dlw, res_alw, res_ono соответственно).

В результате запрос выдаёт в JQuery таблицу типа group_id, group_name, rule_status
Где group_id и group_name - соответствуют оригиналу, а rule_status выдаёт res_dlw/res_alw/res_ono (число/число/число)

Число - это сумма значений из rule_status соответствующих res_dlw, res_alw, res_ono.
То есть если у одного group_id (например 5) с разными cam_id (например 2 и 15) одинаковые значение столбца rule_status res_dlw (это 0), то должно вывестись 2/0/0, а выводится 4/0/0.
Или например 2/1/0, а выводится 6/3/0.

Получается, что при подсчёте запрос помимо желаемого складывания ещё и умножает каждое значение на общую сумму res_dlw + res_alw + res_ono, то есть 2*3/1*3/0*3

Так что MySQL не перестаёт удивлять (или это просто создатель запроса где-то сильно затупил). Если кто сможет помочь, буду чрезвычайно благодарен!
trew
Дата: 28.01.2013 14:36:11
Jops,

одного group_id (например 5) с разными cam_id (например 2 и 15) одинаковые
В таблице cams_rules_groups две записи

...
as crg ON crgg.group_id = crg.group_id
т.е. подсчитали количество, оно равно 2

а теперь соединяем с cams_rules_groups и записи множатся.
Jops
Дата: 28.01.2013 15:21:31
ООО! Это неплохо! Надо поразмыслить как это дело переделать) Хотя если при отсутствии ON crgg.group_id = crg.group_id он помоему ахинею выдаёт. Но спасибо за предложение.
AlexeyVD
Дата: 28.01.2013 15:41:27
Jops,

Несколько раз перечитал 1 пост и вроде как понял, что нужно просто посчитать количество различных rule_status для каждой определенной group_id. Если так, то возникает вопрос - что это у вас за SQL-огород тут понаписан? Поправьте меня, если я не прав:
SELECT g.group_id,
       g.group_name,
       SUM(c.rule_status = 0) AS res_dlw,
       SUM(c.rule_status = 1) AS res_alw,
       SUM(c.rule_status = 2) AS res_ono
  FROM cams_rules_groups c
  JOIN cams_groups g ON c.group_id = g.group_id
  GROUP BY g.group_name, g.group_id
Jops
Дата: 28.01.2013 15:54:46
Писал не я, а в запросах я пока не силён. Но вам огромнейшее спасибо за подсказанный вариант! Всё отрабатывается как надо. Ещё раз СПАСИБо!
Jops
Дата: 28.01.2013 15:58:49
Правда одно вы упустили. Нужно выводить список всех group_id group_name, даже если их res_dlw/res_alw/res_ono = 0/0/0 ))
tanglir
Дата: 28.01.2013 16:03:50
Jops
упустили
left join
ЗЫ. Да что это за эпидемия такая началась? :)
AlexeyVD
Дата: 28.01.2013 16:07:27
Jops,

Нужно просто внешнее соединение тут использовать:
SELECT g.group_id,
       g.group_name,
       SUM(c.rule_status = 0) AS res_dlw,
       SUM(c.rule_status = 1) AS res_alw,
       SUM(c.rule_status = 2) AS res_ono
  FROM cams_groups g
  LEFT JOIN cams_rules_groups c ON c.group_id = g.group_id
  GROUP BY g.group_name, g.group_id
Jops
Дата: 28.01.2013 16:11:56
Согласен! Вариант, если бы не null, который выводится в виде null/null/null, а не 0/0/0 (Извеняюсь за навящивость и дотошность)
tanglir
Дата: 28.01.2013 16:13:01
Use the ifnull, Jops!
А лучше прочитайте букварь.