I’m trying to write a query that selects from four tables
- campaignSentParent csp
- campaignSentEmail cse
- campaignSentFax csf
- campaignSentSms css
Each of the cse, csf, and css tables are linked to the csp table by csp.id = (cse/csf/css).parentId
The csp table has a column called campaignId,
What I want to do is end up with rows that look like:
| id | dateSent | emailsSent | faxsSent | smssSent | | 1 | 2011-02-04 | 139 | 129 | 140 |
But instead I end up with a row that looks like:
| 1 | 2011-02-03 | 2510340 | 2510340 | 2510340 |
Here is the query I am trying
SELECT csp.id id, csp.dateSent dateSent,
COUNT(cse.parentId) emailsSent,
COUNT(csf.parentId) faxsSent,
COUNT(css.parentId) smsSent
FROM campaignSentParent csp,
campaignSentEmail cse,
campaignSentFax csf,
campaignSentSms css
WHERE csp.campaignId = 1
AND csf.parentId = csp.id
AND cse.parentId = csp.id
AND css.parentId = csp.id;
Adding GROUP BY did not help, so I am posting the create statements.
csp
CREATE TABLE `campaignsentparent` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`campaignId` int(11) NOT NULL,
`dateSent` datetime NOT NULL,
`account` int(11) NOT NULL,
`status` varchar(15) NOT NULL DEFAULT 'Creating',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
cse/csf (same structure, different names)
CREATE TABLE `campaignsentemail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parentId` int(11) NOT NULL,
`contactId` int(11) NOT NULL,
`content` text,
`subject` text,
`status` varchar(15) DEFAULT 'Pending',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=140 DEFAULT CHARSET=latin1
css
CREATE TABLE `campaignsentsms` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parentId` int(11) NOT NULL,
`contactId` int(11) NOT NULL,
`content` text,
`status` varchar(15) DEFAULT 'Pending',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=141 DEFAULT CHARSET=latin1
You need to aggregate the sums separately, not as shown in the question.
To do this, you pretty much have to use the JOIN notation as shown.
You depending on the quality of your optimizer and the cardinalities of the various tables and the available indexes, you might find it effective to include a join with CampaignSentParent in each of the sub-queries with the
csp.CampaignID = 1condition, so as to limit the data aggregated by the sub-queries.You might notice that the result count you get is 2510340. The prime factorization of 2510340 is 2 × 2 × 3 × 5 × 7 × 43 × 139, and your expected answer is 139, 129, and 140. You can get 3 × 43 = 129; 2 × 2 × 5 × 7 = 140; and 139 = 139. In other words, the original query is generating the Cartesian product of all the rows in the three dependent tables and counting the product, rather than counting the relevant rows from each dependent table separately.