Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Имеется таблица с полем "idGroup", которое может содержать одно из трех (ENUM) значений: "memory", "old" или "enterprize".
Существует запрос след. вида:
SELECT idGroup, COUNT(*) AS countRecord
FROM table1
GROUP BY idGroup
ORDER BY countRecord
В результате запроса видим, сколько записей принадлежит каждой группе в таком виде:
===
old...........| 13
enterprize.| 24
memory...| 41
===
С течением времени в этой таблице постоянно меняется количество строк (рядов) в пределах сотни.
Изменившиеся условия работы программы (динамика и рваное расписание) привели к возможности, когда в этой таблице в некоторое время может оказаться 0 (ноль) записей принадлежащих к одной или нескольким группам. Т.е. примерно так:
===
old...........| 0 -- этой строки в результате запроса нет (выводится только две следующие, но именно ее очень хотелось бы видеть)
enterprize.| 24
memory...| 41
===
Ранее подобная ситуация была очень редкой, и видимо не попадала под вышеуказанный запрос чтения.
И собственно вопрос. Возможно ли модифицировать запрос? Так, чтобы он выводил группы с нулевым содержанием, т.е. например так:
===
old...........| 0
enterprize.| 0
memory...| 18
===
Пробовал копать в сторону функций управления потоком программы (IF, IFNULL и др.), но все эксперименты завершились неудачно.
Конечно можно оставить в таблице 3 штуки контрольных записей. Но теряется красота
Спасибо!
Отредактированно valich (03.07.2009 09:41:28)
Неактивен
Боюсь, что тут можно сделать только каких-то страшных запросов-уродцев. С другой
стороны, на 300 строчках можно и поизголяться
Подозреваю, что вот такой уродец будет выполнять поставленную задачу:
SELECT b.idGroup, count(b.*)
FROM (SELECT 'memory' a UNION SELECT 'old' UNION SELECT 'enterprise') a
LEFT JOIN table1 b ON (a.a = b.idGroup)
GROUP BY 1
Неактивен
Забыл в условии указать, что в "ноль" записей может уйти любая группа, или несколько.
Ночь мучений все-таки не прошла даром
Поразмыслив пришел к выводу: когда записей для какой-то группы в таблице нет, то их нет, т.е. просто физически нет. А значит вернуть их количество может функция COUNT(*), она по документации работает со значениями NULL. Что на экспериментальных данных вполне соответствует документации. Но это пока не свернешь результаты по GROUP BY, именно здесь исчезают в небытие строки с NULL-значением возвращенным функцией COUNT(*). Как их заставить остаться я даже примерно не понимаю.
Пришел к двум монстрообразным решениям, первый требует создания опорной таблицы-справочника групп. Тогда запрос выглядит примерно так:
===
SELECT dG.idGroup, COUNT(t1.idGroup) AS countRecord
FROM dirGroup dG
LEFT JOIN table1 t1
ON dG.idGroup = t1.idGroup
WHERE (t1.idGroup IS NULL OR t1.idGroup IS NOT NULL)
AND (t1.idStatus = 'active' OR t1.idStatus IS NULL)
GROUP BY t1.idGroup
ORDER BY countRecord
===
Здесь запись в опорной таблице принудительно оставит требуемые строки, при условии:
===
WHERE (t1.idGroup IS NULL OR t1.idGroup IS NOT NULL)
===
Правда, если потребуется применить еще условия в раздел WHERE то каждый из них будет учитывать, что он сам может быть NULL:
===
AND (t1.idStatus = 'active' OR t1.idStatus IS NULL)
===
У меня поле idStatus указан как NOT NULL, при создании таблицы. Так что целостность данных не нарушается.
Второй вариант не требует создания дополнительных таблиц.
===
(SELECT @myGroup:="old" AS idGroup, COUNT(*) AS countRecord
FROM table1 t1
WHERE t1.idGroup = "old")
UNION
(SELECT @myGroup:="memory" AS idGroup, COUNT(*) AS countRecord
FROM table1 t1
WHERE t1.idGroup = "memory")
UNION
(SELECT @myGroup:="enterprize" AS idGroup, COUNT(*) AS countRecord
FROM table1 t1
WHERE t1.idGroup = "enterprize")
ORDER BY countRecord
===
Посмотрел на тестовых данных, вроде все варианты поведения таблицы учитываются.
to paulus: Ваш вариант красивее, спасибо. Счас попробую обкатать
Неактивен
Страниц: 1