如果解决方案显而易见,请提前抱歉.我已搜索但尚未找到解决方案.
我有一个包含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)
你可以在没有自我加入的情况下做到这一点,只需聚合:
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)
设置小提琴
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 检查执行计划。看起来第一种方法中发生了更多的事情。但并不意味着当你在生产中使用时,情况会差很多。