Reputation: 1
I have 3 tables (schema below) and I'm trying to determine how many customers have a flag per category. When I try and use a sub query it just keeps counting how many people have a flag regardless of the category. I've tried adding the group by in the sub query but that doesn't seem to help. I'm sure this is more simple than I'm making it.
*In addition, I need to total count of customers in the same output which I think requires it to have a sub query
SELECT p.category, (SELECT count(c.customer_id) from Customer c where c.flag = 'y') as Flagged
from Product p
LEFT JOIN `Orders` o ON p.product_id = o.product_id
LEFT JOIN `Customer` c ON o.customer_id = c.customer_id
group by category;
**Schema SQL**
CREATE TABLE IF NOT EXISTS `Customer` (
`customer_id` varchar(6),
`name` varchar(6),
`flag` varchar(1),
PRIMARY KEY (`customer_id`)
) DEFAULT CHARSET=utf8;
INSERT INTO Customer VALUES ('000001', 'matt', 'n');
INSERT INTO Customer VALUES ('000002', 'julia', 'y');
INSERT INTO Customer VALUES ('000003', 'carol', 'n');
INSERT INTO Customer VALUES ('000004', 'Riggs', 'n');
CREATE TABLE IF NOT EXISTS `Orders` (
`order_id` varchar(3),
`order_item_id` varchar(3),
`customer_id` varchar(6),
`date` date,
`product_id` varchar(4),
PRIMARY KEY (`customer_id`,`product_id`)
) DEFAULT CHARSET=utf8;
INSERT INTO Orders VALUES ('aaa', 'xxx', '000001','1.1.2018',"prd1");
INSERT INTO Orders VALUES ('bbb', 'yyy', '000001','1.1.2018',"prd2");
INSERT INTO Orders VALUES ('ccc', 'zzz', '000002','1.1.2018',"prd3");
INSERT INTO Orders VALUES ('ddd', 'www', '000003','1.1.2018',"prd4");
CREATE TABLE IF NOT EXISTS `Product` (
`product_id` varchar(4),
`name` varchar(6),
`category` varchar(7),
PRIMARY KEY (`product_id`)
) DEFAULT CHARSET=utf8;
INSERT INTO Product VALUES ('prd1', 'nam1', 'Speaker');
INSERT INTO Product VALUES ('prd2', 'nam2', 'Speaker');
INSERT INTO Product VALUES ('prd3', 'nam3', 'Phone');
INSERT INTO Product VALUES ('prd4', 'nam4', 'Phone');
Upvotes: 0
Views: 58
Reputation: 10035
You may try the following amendment.
It uses LEFT JOIN
to ensure that we will capture all product categories. Moreover it joins customers on c.customer_id = o.customer_id AND c.flag='y'
ensuring we only capture flagged customers. Finally it uses COUNT(c.customer_id)
to count the flagged customers. If there are no flagged customers for a product category that customer_id
will be NULL
and count will ignore nulls, thereby only counting flagged customer ids.
SELECT
p.category, COUNT(c.customer_id) as Flagged
FROM
Product p
LEFT JOIN
Orders o ON p.product_id=o.product_id
LEFT JOIN
Customer c ON c.customer_id = o.customer_id AND
c.flag='y'
GROUP BY
p.category;
category | Flagged |
---|---|
Speaker | 0 |
Phone | 1 |
Edit 1: Also including total customers.
SELECT
p.category,
SUM(IF(c.flag='y',1,0)) as Flagged,
COUNT(DISTINCT c.customer_id) as total_customers
FROM
Product p
LEFT JOIN
Orders o ON p.product_id=o.product_id
LEFT JOIN
Customer c ON c.customer_id = o.customer_id
GROUP BY
p.category;
category | Flagged | total_customers |
---|---|---|
Speaker | 0 | 1 |
Phone | 1 | 2 |
Let me know if this works for you.
Upvotes: 1