首页 > 解决方案 > 按子查询分组?

问题描述

我有 3 个表(下面的模式),我试图确定每个类别有多少客户有一个标志。当我尝试使用子查询时,它只会不断计算有多少人拥有标志,而不管类别如何。我尝试在子查询中添加 group by,但这似乎没有帮助。我敢肯定这比我做的要简单。

*此外,我需要计算同一输出中的客户总数,我认为这需要它有一个子查询

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');

标签: mysqlsql

解决方案


您可以尝试以下修改。

它用于LEFT JOIN确保我们将捕获所有产品类别。此外,它与客户一起c.customer_id = o.customer_id AND c.flag='y'确保我们只捕获标记的客户。最后,它用于COUNT(c.customer_id)计算标记的客户。如果某个产品类别没有标记的客户,customer_idNULLcount 将忽略空值,从而仅计算标记的客户 ID。

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;
类别 已标记
扬声器 0
电话 1

在 DB Fiddle 上查看

编辑 1: 还包括总客户。

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;
类别 已标记 总客户
扬声器 0 1
电话 1 2

在 DB Fiddle 上查看

让我知道这是否适合您。


推荐阅读