Reputation: 53531
I have these tables :
mysql> desc mod_asterisk_booking;
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| uid | int(10) unsigned | NO | | NULL | |
| server_id | int(10) unsigned | NO | | NULL | |
| date_call | datetime | NO | | NULL | |
| participants | int(10) unsigned | NO | | NULL | |
| ... |
+---------------+------------------+------+-----+---------+----------------+
mysql> desc mod_asterisk_servers;
+-------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(32) | NO | | NULL | |
| channels_capacity | int(10) unsigned | NO | | NULL | |
| ... |
+-------------------+------------------+------+-----+---------+----------------+
mysql> desc mod_asterisk_server_phones;
+------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| server_id | int(10) unsigned | NO | | NULL | |
| phone_number | varchar(15) | NO | | NULL | |
| phone_alias | varchar(15) | NO | | NULL | |
| extension | int(10) unsigned | NO | | NULL | |
| is_toll_free | tinyint(1) | NO | | 0 | |
| is_allow_foreign | tinyint(1) | NO | | 0 | |
+------------------+------------------+------+-----+---------+----------------+
The goal is to fetch a server (from mod_asterisk_servers
) that has the enough channels available for a given date interval. This query
SELECT s.*,
s.`channels_capacity` - IFNULL(SUM(b.`participants`), 0) as 'channels_available'
FROM `mod_asterisk_servers` as s
LEFT JOIN `mod_asterisk_booking` as b ON (b.server_id=s.id AND (b.date_call BETWEEN '2011-07-30 15:15:00' AND '2011-07-30 17:15:00'))
GROUP BY s.id
ORDER BY 'channels_available' DESC;
could return something like :
+----+-------------+-----+------------------+--------------------+
| id | name | ... |channels_capacity | channels_available |
+----+-------------+-----+------------------+--------------------+
| 1 | Test server | ... | 150 | 140 |
+----+-------------+-----+------------------+--------------------+
Now, I'd like to add some columns to this query; notably the phone numbers associated with each server found. A phone number may have these combination :
is_toll_free=0 AND is_allow_foreign=0
)is_toll_free=1 AND is_allow_foreign=0
)is_toll_free=1 AND is_allow_foreign=1
)I tried this query
SELECT s.*,
s.`channels_capacity` - IFNULL(SUM(b.`participants`), 0) as 'channels_available',
count(p1.phone_number) as 'local_phones',
count(p2.phone_number) as 'toll_free_phones',
count(p3.phone_number) as 'allow_foreign_phones'
FROM `mod_asterisk_servers` as s
LEFT JOIN `mod_asterisk_booking` as b ON (b.server_id=s.id AND (b.date_call BETWEEN '2011-07-30 15:15:00' AND '2011-07-30 17:15:00'))
LEFT JOIN `mod_asterisk_server_phones` as p1 ON (p1.server_id=s.id AND p1.is_toll_free=0 AND p1.is_allow_foreign=0)
LEFT JOIN `mod_asterisk_server_phones` as p2 ON (p2.server_id=s.id AND p2.is_toll_free=1 AND p2.is_allow_foreign=0)
LEFT JOIN `mod_asterisk_server_phones` as p3 ON (p3.server_id=s.id AND p3.is_toll_free=1 AND p3.is_allow_foreign=1)
ORDER BY 'channels_available' DESC;
but it returns
+----+-------------+-----+-------------------+--------------------+--------------+------------------+----------------------+
| id | name | ... | channels_capacity | channels_available | local_phones | toll_free_phones | allow_foreign_phones |
+----+-------------+-----+-------------------+--------------------+--------------+------------------+----------------------+
| 1 | Test server | ... | 150 | 140 | 2 | 2 | 2 |
+----+-------------+-----+-------------------+--------------------+--------------+------------------+----------------------+
even though there are only three numbers for that server :
mysql> select * from mod_asterisk_server_phones where server_id = 1;
+----+-----------+----------------+-------------+-----------+--------------+------------------+
| id | server_id | phone_number | phone_alias | extension | is_toll_free | is_allow_foreign |
+----+-----------+----------------+-------------+-----------+--------------+------------------+
| 1 | 1 | XXX-XXX-XXXX | | XXXX | 0 | 0 |
| 2 | 1 | 1-800-XXX-XXXX | | XXXX | 1 | 0 |
| 3 | 1 | 1-800-XXX-XXXX | | XXXX | 1 | 1 |
+----+-----------+----------------+-------------+-----------+--------------+------------------+
Maybe someone with better understanding of SQL can help me figure out this one?
Thanks!
Upvotes: 0
Views: 91
Reputation: 37354
Try count(DISTINCT p1.phone_number)
instead of count(p1.phone_number)
(and the same for p2,p3). And don't forget the proper GROUP BY
Upvotes: 1