![]() |
![]() |
Задавайте вопросы, мы ответим
Вы не зашли.
Приветствую, уважаемые!
В поисках истины вновь на вашем замечательном сайте
Чтобы не грузить подробностями смоделирую задачу.
Eсть 2 идентичные таблицы `yan` и `feb`:
CREATE TABLE IF NOT EXISTS `yan` (
`point` int(3) NOT NULL,
`cell` int(3) NOT NULL,
`all` int(5) NOT NULL DEFAULT '0',
`on01` int(5) NOT NULL DEFAULT '0',
`on10` int(5) NOT NULL DEFAULT '0',
`on20` int(5) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
В таблицах хранятся сводные данные по количеству пользователей, скажем, уплативших за какие-то услуги на конкретные числа месяца.
Для примера возьмем 2 месяца. И еще одно из "нереальных" условий - каждый жилец платит за себя отдельно.
`point` - это количество больших объектов, скажем домов
`cell` - количество квартир в каждом из домов
`all` - количество жильцов в каждой квартире
`on01`, `on10`, `on20` - количество заплативших на 1, 10 и 20-е число соответственно
Пытаюсь одним запросом получить сводные данные по домам за последний месяц (в нашем случае февраль) `aon01`...`aon20` и получить разницу с январем `ron01`...`ron20`.
SELECT a.`point`, COUNT(a.`cell`) AS `acell`,
SUM(a.`all`) AS `aall`, SUM(a.`all`)-SUM(b.`all`) AS `rall`,
SUM(a.`on01`) AS `aon01`, SUM(a.`on01`)-SUM(b.`on01`) AS `ron01`,
SUM(a.`on10`) AS `aon10`, SUM(a.`on10`)-SUM(b.`on10`) AS `ron10`,
SUM(a.`on20`) AS `aon20`, SUM(a.`on20`)-SUM(b.`on20`) AS `ron20`
FROM `feb` AS a
LEFT JOIN `yan` AS b ON ( a.`point`=b.`point` )
GROUP BY a.`point`
ORDER BY a.`point`
`acell` - количество квартир в каждом доме
`aall` и `rall` - количество жильцов в доме и разница с прошлым месяцем соответственно
`aon01` и `ron01` - количество уплативших за февраль и разница с январем соответственно
Вопросов 3, но все по теме, потому прошу сильно не бить :
1. Как или почему в результатах по домам получаются все значения умноженными на количество квартир в доме (`acell`)?
2. Почему мускул ругается на такую запись:
... SUM(a.`on01`) AS `aon01`, `aon01`-SUM(b.`on01`) AS `ron01`, ...
3. Почему не работают переменные в таком варианте:
... (@on01=SUM(a.`on01`)) AS `aon01`, (@on01-SUM(b.`on01`)) AS `ron01`, ...
Благодарю за помощь
Неактивен
А почему count(), а не sum()?
1. Объединение таблиц — это по сути их произведение. Т.е. если не накладывать
никаких дополнительных условий, то будет возвращено строк столько, сколько
в одной таблице × количество строк в другой таблице. Соотвественно, если Вы
группируете по данным из одной таблицы, то количество строк не уменьшается.
Отсюда и произведение. Можно или делить, или писать более разумные запросы.
2. Ругается потому что нельзя смешивать просто переменную и групповую операцию.
Подумайте, что бы Вы сказали человеку, если бы он у Вас спросил «расскажи мне,
что будет, если из количества листьев на деревьях в этом саду вычесть вот тот дуб»?
3. Потому что даже если дуб замаскировать под переменную, он останется дубом.
--
Сделайте хитрую табличку «разницы», а потом группируйте уже в ней. Не обязательно
физическую, можно как подзапрос.
Неактивен