在同一个表上连接的SQL计数查询

Poi*_*int 5 sql join

如果解决方案显而易见,请提前抱歉.我已搜索但尚未找到解决方案.

我有一个包含2列的Orders表:CustID和ProductBrand.ProductBrand是订购商品的品牌,例如索尼,惠普,戴尔等.

我想获得订购至少10件产品的客户列表,其中ProductBrand = Sony但少于5件产品的商品牌= HP.

我可以用这些方法做些什么吗?

SELECT o1.CustID
FROM Orders o1 HAVING COUNT(o1.ProductBrand="Sony") >= 10
INNER JOIN Orders o2 ON o1.CustID = o2.CustID
HAVING COUNT(o2.ProductBrand="HP") < 5;
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 5

你可以在没有自我加入的情况下做到这一点,只需聚合:

select o.custid
from orders o
group by o.custid
having sum(case when o.ProductBrand = 'Sony' then 1 else 0 end) >= 10 and
       sum(case when o.ProductBrand = 'HP' then 1 else 0 end) < 5;
Run Code Online (Sandbox Code Playgroud)

在MySQL中,您可以通过删除以下内容来简化case:

select o.custid
from orders o
group by o.custid
having sum(o.ProductBrand = 'Sony') >= 10 and
       sum(o.ProductBrand = 'HP') < 5;
Run Code Online (Sandbox Code Playgroud)


T.S*_*.S. 0

设置小提琴

CREATE TABLE ORDERS (cust INT, brand VARCHAR(100))

INSERT INTO ORDERS VALUES (1, 'Sony')
INSERT INTO ORDERS VALUES (1, 'Sony')
INSERT INTO ORDERS VALUES (1, 'Sony')
INSERT INTO ORDERS VALUES (1, 'Hp')
INSERT INTO ORDERS VALUES (1, 'Hp')
INSERT INTO ORDERS VALUES (2, 'Sony')
INSERT INTO ORDERS VALUES (2, 'Sony')
INSERT INTO ORDERS VALUES (2, 'Hp')
INSERT INTO ORDERS VALUES (2, 'Hp')
INSERT INTO ORDERS VALUES (2, 'Hp')
INSERT INTO ORDERS VALUES (2, 'Hp')
INSERT INTO ORDERS VALUES (3, 'Sony')
INSERT INTO ORDERS VALUES (3, 'Sony')
INSERT INTO ORDERS VALUES (3, 'Sony')
INSERT INTO ORDERS VALUES (3, 'Hp')
INSERT INTO ORDERS VALUES (3, 'Hp')
Run Code Online (Sandbox Code Playgroud)

询问

方法一

select 
    sony.custId 
from 
    (select cust as custId, Brand, count(*) as count 
     from orders 
     where Brand = 'Sony' 
     group by cust, brand) Sony 
         inner join 
     (select cust as custId, Brand, count(*) as count 
      from orders 
      where Brand = 'Hp' 
      group by cust, brand) Hp 
          on sony.custId = hp.CustId 
Where 
    sony.count > 2 and 
    hp.count < 5
Run Code Online (Sandbox Code Playgroud)

这有利于你理解关系。这是另一种方法

方法2

select cust  
from orders 
group by cust, brand
having  count(case brand when 'Sony' then 'x' end) > 2 and 
        count(case brand when 'Hp' then 'x' end) < 5
Run Code Online (Sandbox Code Playgroud)

时间大致相同 - 当然它会根据数据量、索引等而有所不同。使用 Sql fiddle 检查执行计划。看起来第一种方法中发生了更多的事情。但并不意味着当你在生产中使用时,情况会差很多。