Двойная группировка?

za-ek
Дата: 07.02.2013 17:52:15
Здравствуйте! Есть таблица и есть задача, я не знаю, как её правильно назвать, поэтому даже не знаю, что искать.

Вот таблица:

+---------+-----------+-----+
| user_id | parent_id | lvl |
+---------+-----------+-----+
| 3959 | 3453 | 1 |
| 3959 | 2919 | 2 |
| 3959 | 2892 | 3 |
| 3959 | 2616 | 4 |
| 3959 | 2592 | 5 |
| 4174 | 3196 | 1 |
| 4174 | 2919 | 2 |
| 4174 | 2892 | 3 |
| 4174 | 2616 | 4 |
| 4174 | 2592 | 5 |
+---------+-----------+-----+

Идея такая : есть пользователь, у него есть дочерние пользователи, вроде это называется сетевой маркетинг, структура такая :
у каждого пользователя на уровне 1 находится 2 пользователя, на уровне 2 - 4, на 3 - 8, 4 - 16 и т.д., также есть таблица, в которой хранятся значения количества пользователей на каждый уровень:

+----+-------+
| id | value |
+----+-------+
| 1 | 2 |
| 2 | 4 |
| 3 | 8 |
| 4 | 16 |
| 5 | 32 |
....


Вот такой вот незамысловатый запрос извлекает данные для пользователя,

автор
SELECT `z_users_lvls`.lvl, count( `z_users_lvls`.user_id ), ( `z_users_lvl_max`.`value` - count( `z_users_lvls`.user_id ) ) as free
FROM `z_users_lvls` RIGHT JOIN `z_users_lvl_max` ON `z_users_lvl_max`.`id` = `z_users_lvls`.`lvl`
WHERE `z_users_lvls`.parent_id =2919 GROUP BY `z_users_lvls`.lvl
HAVING (count( `z_users_lvls`.user_id ) < (SELECT `value` FROM z_users_lvl_max WHERE id = z_users_lvls.lvl))
ORDER BY `z_users_lvls`.`lvl` ASC

Результат:
+------+---------------------------------+------+
| lvl | count( `z_users_lvls`.user_id ) | free |
+------+---------------------------------+------+
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 1 | 7 |
+------+---------------------------------+------+


А теперь мне нужно извлечь для всех пользователей значения свободных мест на каждом уровне, вот я немного заступорился, что тут использовать? Группировать, получается, нужно и по колонке lvl и по колонке parent_id?
javajdbc
Дата: 07.02.2013 19:09:05
если вас устраивает как работает первый запрос, то
можно использовать его как подзапрос и
делать любые следуюшие агрегации:

select
.... sum()
.... max()...
FROM
( первый селект ) zz
group by ....
za-ek
Дата: 07.02.2013 20:12:55
В запросе используется id пользователя, а необходимо вывести данные по всем пользователям
qwerty112
Дата: 08.02.2013 02:22:18
za-ek,

select t1.user_id, t1.lvl, t2.value-count(*) as xz
from t1 inner join t2 on t1.lvl=t2.id
group by t1.user_id, t1.lvl, t2.value


по уму, тут нужно ещё таб.юзеров использовать,
потому как, если у юзера на каком-то уровне нет совсем дочерн.записей,
то такой уровень, для этого юзера - не выведется