MySQL database : how to write SQL for several tables - mysql

I need to create a view for client shipment documents which contains next info:
good name,
good count
good price.
Price may be different from one purchase agreement to other. For each purchase agreement may exists several shipments. Each good item in client_shipment_details may has serial number, but client_shipment document
keeps just total count of such kind of good.
This is my tables:
purchase_agreement;
+------------------------------+--------------+------+-----+---------+-------- --------+
| Field | Type | Null | Key | Default | Extra |
+------------------------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| purchase_agreement_status_id | bigint(20) | YES | MUL | NULL | |
+------------------------------+--------------+------+-----+---------+----------------+
purchase_agreement_details;
+-----------------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| count | int(11) | NO | | NULL | |
| price | float | NO | | NULL | |
| purchase_agreement_id | bigint(20) | YES | MUL | NULL | |
| good_id | bigint(20) | YES | MUL | NULL | |
+-----------------------+------------+------+-----+---------+----------------+
goods;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
client_shipment;
-----------------------+--------------+------+-----+---------+---------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| jhi_date | datetime | YES | | NULL | |
| purchase_agreement_id | bigint(20) | YES | MUL | NULL | |
+-----------------------+--------------+------+-----+---------+----------------+
client_shipment_details;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
|
| serial_number | varchar(255) | YES | | NULL | |
| client_shipment_id | bigint(20) | YES | MUL | NULL | |
| good_id | bigint(20) | YES | MUL | NULL | |
+--------------------+--------------+------+-----+---------+----------------+
This is my query :
SELECT
temp1.cs_id, temp1.good_id, temp1.count, temp1.price,good.name
FROM
(
SELECT csd.cs_id AS cs_id, csd.good_id AS good_id, csd.count AS count, pad.price AS price
FROM
(
SELECT client_shipment_id AS cs_id, good_id, count(*) AS count
FROM client_shipment_details
GROUP BY client_shipment_id, good_id
) AS csd
LEFT JOIN
(
SELECT pad.good_id AS good_id, pad.price AS price, cs.id AS cs_id
FROM purchase_agreement_details pad
JOIN client_shipment cs ON pad.purchase_agreement_id = cs.purchase_agreement_id
) AS pad ON csd.good_id = pad.good_id
GROUP BY cs_id,good_id
) AS temp1
JOIN goods ON temp1.good_id = good.id
ORDER BY cs_id,good_id;
Some test data:
insert into purchase_agreement values
(1,1),
(2,1);
insert into purchase_agreement_details values
(1,2,100,1,1),
(2,4,200,1,2),
(3,6,300,1,3),
(4,7,400,1,4),
(5,3,110,2,1),
(6,8,210,2,2),
(7,4,310,2,3),
(8,5,410,2,4);
insert into goods values
(1,"desk"),
(2,"sofa"),
(3,"chair"),
(4,"bed");
insert into client_shipment values
(1,'2019-02-21 09:57:00',1),
(2,'2019-02-21 09:57:00',1),
(3,'2019-02-21 09:57:00',2),
(4,'2019-02-21 09:57:00',2);
insert into client_shipment_details values
(1,"1-0001",1,1),
(2,"1-0002",1,1),
(3,"2-0001",1,2),
(4,"2-0002",1,2),
(5,"3-0001",1,3),
(6,"3-0002",1,3),
(7,"4-0001",1,4),
(8,"4-0002",1,4),
(9,"1-0003",2,1),
(10,"1-0004",2,1),
(11,"2-0003",2,2),
(12,"2-0004",2,2),
(13,"3-0003",2,3),
(14,"3-0004",2,3),
(15,"4-0003",2,4),
(16,"4-0004",2,4),
(17,"1-0005",3,1),
(18,"1-0006",3,1),
(19,"2-0005",3,2),
(20,"2-0006",3,2),
(21,"3-0005",3,3),
(22,"3-0006",3,3),
(23,"4-0005",3,4),
(24,"4-0006",3,4),
(25,"1-0007",4,1),
(26,"1-0008",4,1),
(27,"2-0007",4,2),
(28,"2-0008",4,2),
(29,"3-0007",4,3),
(30,"3-0008",4,3),
(31,"4-0007",4,4),
(32,"4-0008",4,4);
I'd like to get such result :
client_shipment_id good_name price count
1 desk 100 2
1 sofa 200 2
1 chair 300 2
1 bed 400 2
2 desk 100 2
2 sofa 200 2
2 chair 300 2
2 bed 400 2
3 desk 110 2
3 sofa 210 2
3 chair 310 2
3 bed 410 2
4 desk 110 2
4 sofa 210 2
4 chair 310 2
4 bed 410 2

Related

Calculate difference between two row amount in MySQL

I am having a table with which calculates balance, where I have these columns in the table:
> describe tbl_credit_log
+------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| visitor_id | int(10) unsigned | YES | MUL | NULL | |
| post_owner_id | int(10) unsigned | YES | MUL | NULL | |
| post_id | int(10) unsigned | YES | MUL | NULL | |
| balance | double(50,6) | YES | | NULL | |
| credits | double(50,6) | YES | | NULL | |
| debits | double(50,6) | YES | | NULL | |
| trans_id | varchar(255) | NO | | NULL | |
| trans_amount | double(50,6) | YES | | NULL | |
| earningtype | varchar(15) | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+------------------+------------------+------+-----+---------+----------------+
Where here is the few entries from which I want to do the calculations :
+---------+------------+---------------+---------+------------------+-------------+-----------+--------+---------------------+
| id | visitor_id | post_owner_id | post_id | advertisement_id | balance | credits | debits | created_at |
+---------+------------+---------------+---------+------------------+-------------+-----------+--------+---------------------+
| 4331666 | 11006 | 11 | NULL | NULL | 3639.624400 | 22.500000 | NULL | 2018-08-10 05:45:37 |
| 4364034 | 7206 | 11 | NULL | NULL | 5139.607900 | 22.500000 | NULL | 2018-08-10 11:02:52 |
| 4377238 | 4353 | 11 | NULL | NULL | 5162.107900 | 22.500000 | NULL | 2018-08-10 12:52:01 |
| 4485288 | 9664 | 11 | NULL | NULL | 5184.607900 | 22.500000 | NULL | 2018-08-11 08:58:19 |
| 4544185 | 11709 | 11 | NULL | NULL | 5207.107900 | 22.500000 | NULL | 2018-08-11 19:06:52 |
| 4550728 | 11970 | 11 | NULL | NULL | 5229.607900 | 22.500000 | NULL | 2018-08-11 20:39:36 |
| 4607317 | 12021 | 11 | NULL | NULL | 5252.107900 | 22.500000 | NULL | 2018-08-12 07:29:17 |
| 4629660 | 11926 | 11 | NULL | NULL | 5274.607900 | 22.500000 | NULL | 2018-08-12 09:18:56 |
| 4725299 | 12088 | 11 | NULL | NULL | 5297.107900 | 22.500000 | NULL | 2018-08-13 01:54:53 |
| 4725347 | 10253 | 11 | NULL | NULL | 5319.607900 | 22.500000 | NULL | 2018-08-13 08:29:46 |
| 4725357 | 12140 | 11 | NULL | NULL | 5342.107900 | 22.500000 | NULL | 2018-08-13 09:27:44 |
+---------+------------+---------------+---------+------------------+-------------+-----------+--------+---------------------+
here we have difference (more then 50) in amount on id number4364034 which I want to find in whole database where user id will be post_owner_id as foreign key.
I want to get all the post_owner_id who have difference in the amount and their created_at.
So the expected results will be something like this
+---------+------------+---------------+---------+------------------+-------------+-----------+--------+---------------------+
| id | visitor_id | post_owner_id | post_id | advertisement_id | balance | credits | debits | created_at |
+---------+------------+---------------+---------+------------------+-------------+-----------+--------+---------------------+
| 4364034 | 7206 | 11 | NULL | NULL | 5139.607900 | 22.500000 | NULL | 2018-08-10 11:02:52 |
+---------+------------+---------------+---------+------------------+-------------+-----------+--------+---------------------+
here we will have multiple post_owner_id. I am showing one post_owner_id because this result is only of one post owner id. But I want to get different post owner id who have difference balance is more then 50.
I am not able to figure out how can I do this. I want to compare prices on group_by post_owner_id and get the row where the difference amount is.
Consider the following:
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,balance DECIMAL(12,6) NOT NULL
,created_at timestamp NOT NULL
);
INSERT INTO my_table VALUES
(4331666,3639.624400,'2018-08-10 05:45:37'),
(4364034,5139.607900,'2018-08-10 11:02:52'),
(4377238,5162.107900,'2018-08-10 12:52:01'),
(4485288,5184.607900,'2018-08-11 08:58:19'),
(4544185,5207.107900,'2018-08-11 19:06:52'),
(4550728,5229.607900,'2018-08-11 20:39:36'),
(4607317,5252.107900,'2018-08-12 07:29:17'),
(4629660,5274.607900,'2018-08-12 09:18:56'),
(4725299,5297.107900,'2018-08-13 01:54:53'),
(4725347,5319.607900,'2018-08-13 08:29:46'),
(4725357,5342.107900,'2018-08-13 09:27:44');
Option 1:
SELECT a.*
FROM
( SELECT x.*
, MIN(y.id) y_id
FROM my_table x
JOIN my_table y
ON y.created_at > x.created_at
GROUP
BY x.id
) a
JOIN my_table b
ON b.id = a.y_id
AND b.balance > a.balance + 50;
+---------+-------------+---------------------+---------+
| id | balance | created_at | y_id |
+---------+-------------+---------------------+---------+
| 4331666 | 3639.624400 | 2018-08-10 05:45:37 | 4364034 |
+---------+-------------+---------------------+---------+
Option 2:
SELECT id
, balance
, created_at
FROM
( SELECT x.*
, #i<balance-50 i
, #i:=balance
FROM my_table x
, (SELECT #i:=null) vars
ORDER
BY created_at
) n
WHERE i = 1;
+---------+-------------+---------------------+
| id | balance | created_at |
+---------+-------------+---------------------+
| 4364034 | 5139.607900 | 2018-08-10 11:02:52 |
+---------+-------------+---------------------+
You can adapt either of the techniques above to return either row

Auto Increment a column in Mysql 5.7 according to another column in table

I have a table like this
+------------------+------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+-------------------+-----------------------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(10) unsigned | NO | | NULL | |
| arena_ids | json | NO | | NULL | |
| organization_id | int(10) unsigned | NO | MUL | NULL | |
| type | tinyint(4) | NO | | NULL | |
| registration_fee | double | YES | | NULL | |
| tax_group_id | int(10) unsigned | YES | MUL | NULL | |
| from_date | date | YES | | NULL | |
| to_date | date | YES | | NULL | |
| status | varchar(10) | YES | | NULL | |
| comments | varchar(100) | YES | | NULL | |
| created_at | datetime | NO | | CURRENT_TIMESTAMP | |
| updated_at | datetime | YES | | NULL | on update CURRENT_TIMESTAMP |
| deleted_at | datetime | YES | | NULL | |
+------------------+------------------+------+-----+-------------------+-----------------------------+
Now in this table I have to add one more column serial number
and that serial number will auto_increment but in my case it is something different I have to increment serial_number until organization_id changes and if organization_id changes so now again
serial_number starts from 1 again.
`serial_number` `organization_id`
1 1
2 1
1 2
3 1
2 2
while i was reading the documentation I found some example like this but I here I have to update not create
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
)
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
How to achieve this thing in update query .

mysql query using 4 tables to produce small report

I'm having trouble getting a query to work. 4 tables are used in this query. I want a report looking like this...
Name Success Failure
jdn 5 1
wer 0 3
I want to produce data for the last 24 hours. Here is a sample query I tried and didn't work.
select r.name as jid,
i.id as theid,
(select sum(counter) as scount
from WebServicesIfSummarySuccess
where id=theid
and dtime between date_sub(now(),interval 24 hour) and now()
and sum(counter) >0 and sum(counter) is not null
group by id
) as success,
(select sum(counter) as fcount
from WebServicesIfSummaryFailure
where id=theid
and dtime between date_sub(now(),interval 24 hour) and now()
and sum(counter) >0 and sum(counter) is not null
group by id
) as failure
from router r, interface i
where r.rid = i.rid
and r.name like '%wi%' ;
Here are the table layouts.
router
+-------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+----------------+
| rid | int(11) unsigned | NO | PRI | NULL | auto_increment |
| name | char(120) | NO | MUL | | |
| pop | char(10) | NO | MUL | | |
| popid | tinyint(3) unsigned | NO | | 0 | |
+-------+---------------------+------+-----+---------+----------------+
interface
+-------------+---------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| name | char(255) | NO | MUL | | |
| rid | int(11) | NO | MUL | 0 | |
| speed | bigint(11) | YES | | NULL | |
| description | char(255) | YES | | NULL | |
| status | enum('active','inactive') | YES | | active | |
+-------------+---------------------------+------+-----+---------+----------------+
Failure and Success are 2 separate tables
+---------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | NO | PRI | NULL | |
| dtime | datetime | NO | PRI | NULL | |
| counter | bigint(20) | NO | | NULL | |
| rate | int(11) | YES | | NULL | |
+---------+------------------+------+-----+---------+-------+

How to make this SQL query faster?

I have the following query:
SELECT DISTINCT `movies_manager_movie`.`id`,
`movies_manager_movie`.`title`,
`movies_manager_movie`.`original_title`,
`movies_manager_movie`.`synopsis`,
`movies_manager_movie`.`keywords`,
`movies_manager_movie`.`release_date`,
`movies_manager_movie`.`rating`,
`movies_manager_movie`.`poster_web_url`,
`movies_manager_movie`.`has_poster`,
`movies_manager_movie`.`number`,
`movies_manager_movie`.`has_sources`,
`movies_manager_movie`.`season_id`,
`movies_manager_movie`.`created`,
`movies_manager_movie`.`updated`,
`movies_manager_moviecache`.`activity_name`
FROM `movies_manager_movie`
LEFT OUTER JOIN `movies_manager_moviecache` ON (`movies_manager_movie`.`id` = `movies_manager_moviecache`.`movie_id`)
WHERE (`movies_manager_movie`.`has_sources` = 1
AND (`movies_manager_moviecache`.`team_member_id` IN (
SELECT U0.`id` FROM `movies_manager_movieteammember` U0
INNER JOIN `movies_manager_movieteammemberactivity` U1 ON (U0.`id` = U1.`team_member_id`)
WHERE U1.`movie_id` = 3588 )
AND `movies_manager_movie`.`number` IS NULL
)
AND NOT (`movies_manager_movie`.`id` = 3588 ))
ORDER BY `movies_manager_moviecache`.`activity_name` DESC LIMIT 3;
This query can take up to 3 seconds and I'm very surprise since I got indexes everywhere and no more than 35 rows in each of my MyIsam tables, using the latest MySQL version.
I cached everything I could but I have at least to run this one 20000 times every day, which is approximately 16 h of waiting for loading. And I'm pretty sure none of my user (nor Google Bot) appreciate a 4 secondes waiting time for each page loading.
What could I do to make it faster ?
I thought about duplicating field from movie to moviecache since the all purpose of movie cache is to denormalize to complex join already.
I tried inlining the subquery to a list of ID but it surprisingly doubled the time of the query.
Tables:
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(120) | NO | UNI | NULL | |
| original_title | varchar(120) | YES | | NULL | |
| synopsis | longtext | YES | | NULL | |
| keywords | varchar(120) | YES | | NULL | |
| release_date | date | YES | | NULL | |
| rating | int(11) | NO | | NULL | |
| poster_web_url | varchar(255) | YES | | NULL | |
| has_poster | tinyint(1) | NO | | NULL | |
| number | int(11) | YES | | NULL | |
| season_id | int(11) | YES | MUL | NULL | |
| created | datetime | NO | | NULL | |
| updated | datetime | NO | | NULL | |
| has_sources | tinyint(1) | NO | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
+---------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(120) | NO | UNI | NULL | |
| biography | longtext | YES | | NULL | |
| birth_date | date | YES | | NULL | |
| picture_web_url | varchar(255) | YES | | NULL | |
| allocine_link | varchar(255) | YES | | NULL | |
| created | datetime | NO | | NULL | |
| updated | datetime | NO | | NULL | |
| has_picture | tinyint(1) | NO | | NULL | |
| biography_linkyfied | longtext | YES | | NULL | |
+---------------------+--------------+------+-----+---------+----------------+
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| movie_id | int(11) | NO | MUL | NULL | |
| tag_slug | varchar(100) | YES | MUL | NULL | |
| team_member_id | int(11) | YES | MUL | NULL | |
| cast_rank | int(11) | YES | | NULL | |
| activity_name | varchar(30) | YES | MUL | NULL | |
+----------------+--------------+------+-----+---------+----------------+
Mysql tells me it's a slow query:
# Query_time: 3 Lock_time: 0 Rows_sent: 9 Rows_examined: 454128
Move movies_manager_movieteammemberactivity and movies_manager_movieteammember to your main join statement (so that you're doing a left outer between movies_manager_movie and the inner join product of the other 3 tables). This should speed up your query considerably.
Try this:
SELECT `movies_manager_movie`.`id`,
`movies_manager_movie`.`title`,
`movies_manager_movie`.`original_title`,
`movies_manager_movie`.`synopsis`,
`movies_manager_movie`.`keywords`,
`movies_manager_movie`.`release_date`,
`movies_manager_movie`.`rating`,
`movies_manager_movie`.`poster_web_url`,
`movies_manager_movie`.`has_poster`,
`movies_manager_movie`.`number`,
`movies_manager_movie`.`has_sources`,
`movies_manager_movie`.`season_id`,
`movies_manager_movie`.`created`,
`movies_manager_movie`.`updated`,
(
SELECT `movies_manager_moviecache`.`activity_name`
FROM `movies_manager_moviecache`
WHERE (`movies_manager_movie`.`id` = `movies_manager_moviecache`.`movie_id`
AND (`movies_manager_moviecache`.`team_member_id` IN (
SELECT U0.`id` FROM `movies_manager_movieteammember` U0
INNER JOIN `movies_manager_movieteammemberactivity` U1 ON (U0.`id` = U1.`team_member_id`)
WHERE U1.`movie_id` = 3588 )
AND `movies_manager_movie`.`number` IS NULL
) ) LIMIT 1) AS `activity_name`
FROM `movies_manager_movie`
WHERE (`movies_manager_movie`.`has_sources` = 1
AND NOT (`movies_manager_movie`.`id` = 3588 ))
ORDER BY `activity_name` DESC
LIMIT 3;
Let me know how that performs

MySQL JOIN and COUNT not coherent

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 :
local phone number (is_toll_free=0 AND is_allow_foreign=0)
toll free number, limited to a given region (is_toll_free=1 AND is_allow_foreign=0)
toll free number, allowing an "extended" region (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!
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