SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 02.07.2009 19:38:28

valich
Участник
Зарегистрирован: 02.07.2009
Сообщений: 2

Как сделать чтобы запрос возвращал кол-во несуществующих строк

Имеется таблица с полем "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 штуки контрольных записей. Но теряется красота smile
Спасибо!

Отредактированно valich (03.07.2009 09:41:28)

Неактивен

 

#2 03.07.2009 01:41:09

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Как сделать чтобы запрос возвращал кол-во несуществующих строк

Боюсь, что тут можно сделать только каких-то страшных запросов-уродцев. С другой
стороны, на 300 строчках можно и поизголяться smile

Подозреваю, что вот такой уродец будет выполнять поставленную задачу:
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

Неактивен

 

#3 03.07.2009 10:14:14

valich
Участник
Зарегистрирован: 02.07.2009
Сообщений: 2

Re: Как сделать чтобы запрос возвращал кол-во несуществующих строк

Забыл в условии указать, что в "ноль" записей может уйти любая группа, или несколько.
Ночь мучений все-таки не прошла даром  smile
Поразмыслив пришел к выводу: когда записей для какой-то группы в таблице нет, то их нет, т.е. просто физически нет. А значит вернуть их количество может функция 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: Ваш вариант красивее, спасибо. Счас попробую обкатать

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson