Chris Wood
Chris Wood

Reputation: 35

Multi table query with sums, One to Many to Many

I have a number of MySQL tables and want to get the sum from each table into a single result set. I am simplifying the tables, but how I would like to present the data:

+--------------+-------------------+----------------+
| CustomerName | Transactions(SUM) | Additions(SUM) |
+--------------+-------------------+----------------+
| Customer1    | 8                 | 6              |
+--------------+-------------------+----------------+
| Customer2    | 24                | 4              |
+--------------+-------------------+----------------+

Each customer has multiple sites, and each site has multiple transactions and additions. We dont need to break it down by site, but do need to get total sums for all the transactions and additions for each customer for the current month/previous month etc.

Table 1: Customers
id, CustomerName

Table 2: Sites    
id, site, CustomerID

Table 3: Transactions
site, price, billingMonth

Table 4: Additions
site, price, date

An example table structure with some basic data. The date stuff can be ignored for what I am trying to achieve. Its just adding unnecessary complication.

/*Table structure for table `additions` */

CREATE TABLE `additions` (
  `site` int(3) DEFAULT NULL,
  `price` int(3) DEFAULT NULL,
  `date` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*Data for the table `additions` */

insert  into `additions`(`site`,`price`,`date`) values 
(1,2,'2019-06-14'),
(1,3,'2019-06-14'),
(2,1,'2019-06-14'),
(3,3,'2019-06-14'),
(4,1,'2019-06-14');

/*Table structure for table `customers` */

CREATE TABLE `customers` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `CustomerName` char(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

/*Data for the table `customers` */

insert  into `customers`(`id`,`CustomerName`) values 
(1,'Customer1'),
(2,'Customer2');

/*Table structure for table `sites` */

CREATE TABLE `sites` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `site` char(10) DEFAULT NULL,
  `customerID` int(3) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

/*Data for the table `sites` */

insert  into `sites`(`id`,`site`,`customerID`) values 
(1,'Location1',1),
(2,'Location2',1),
(3,'Location3',2),
(4,'Location4',2);

/*Table structure for table `transactions` */

CREATE TABLE `transactions` (
  `site` int(3) DEFAULT NULL,
  `price` int(3) DEFAULT NULL,
  `billingMonth` char(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*Data for the table `transactions` */

insert  into `transactions`(`site`,`price`,`billingMonth`) values 
(1,1,'Jun-2019'),
(2,3,'Jun-2019'),
(3,23,'Jun-2019'),
(4,1,'Jun-2019'),
(1,2,'Jun-2019'),
(2,2,'Jun-2019');

The query I am trying is as follows:

SELECT `customers`.`CustomerName`, SUM(`transactions`.`price`), SUM(`additions`.`price`)
FROM `customers`
JOIN `sites` ON `customers`.`id` = `sites`.`customerID`
JOIN `transactions` ON `sites`.`id` = `transactions`.`site`
JOIN `additions` ON `sites`.`id` = `additions`.`site`
GROUP BY `customers`.`CustomerName`

However this is returning the wrong results:

+--------------+-------------------+----------------+
| CustomerName | Transactions(SUM) | Additions(SUM) |
+--------------+-------------------+----------------+
| Customer1    | 11                | 12             |
+--------------+-------------------+----------------+
| Customer2    | 24                | 4              |
+--------------+-------------------+----------------+

Upvotes: 0

Views: 54

Answers (1)

Harshwardhan Sharma
Harshwardhan Sharma

Reputation: 261

May be it can help

SELECT C.CustomerName,T.TransactionsSum,A.AdditionsSum FROM `customers` AS C 
LEFT JOIN (SELECT customerID,sum(T1.price) AS TransactionsSum FROM sites AS S 
        LEFT JOIN transactions AS T1 ON S.id = T1.site
        GROUP By S.customerID) AS T ON C.id = T.customerID
LEFT JOIN (SELECT customerID,sum(A1.price) AS AdditionsSum FROM sites AS S 
        LEFT JOIN additions AS A1 ON S.id = A1.site
        GROUP By S.customerID) AS A ON C.id = A.customerID

Upvotes: 1

Related Questions