我的问题是找到所有那些已经达到最低和最高无订单的客户。
我能想出的是:
select customer_id , count(order_id) as num
from bab_customer right outer join bab_order_details using(customer_id)
group by customer_id
having count(order_id) >=
all(select count(order_id)
from bab_customer right outer join bab_order_details using(customer_id)
group by customer_id)
or count(order_id) <=
all(select count(order_id)
from bab_customer right outer join bab_order_details using(customer_id)
group by customer_id);
它给了我正确的输出,但我必须做同样的连接3次。有更好的方法吗?
答案 0 :(得分:2)
这样更好吗?我不知道......
SELECT x.*
FROM
( SELECT customer_id
, COUNT(*) cnt
FROM orders
GROUP
BY customer_id
) x
JOIN
( SELECT MIN(cnt) min_cnt
, MAX(cnt) max_cnt
FROM
( SELECT customer_id
, COUNT(*) cnt
FROM orders
GROUP
BY customer_id
) n
) y
ON y.min_cnt = x.cnt
OR y.max_cnt = x.cnt;
答案 1 :(得分:1)
我意识到,如果不多次调用相同的子查询,就无法在单个查询中运行它。当您引用min(numOrders)和max(numOrders)时,您必须将numOrders存储为时态表或计算两次。如果请求相同,DBMS很可能会缓存您的请求,因此您不必担心浪费资源。
所以你的查询必须有点重写并且足够好。我的变种是
select customer_id , count(order_id) as num
from customers right outer join orders using(customer_id)
group by customer_id
having
num = (SELECT min(num) FROM (select count(order_id) as num
from customers right outer join orders using(customer_id)
group by customer_id) numOrders)
or
num = (SELECT max(num) FROM (select count(order_id) as num
from customers right outer join orders using(customer_id)
group by customer_id) numOrders)
您可以使用此sqlfiddle
进行检查答案 2 :(得分:0)
如果我绝对觉得这必须是一个查询,我可能只使用union all
。
(
select
customer_id,
count(*) as num
from bab_customer right outer join bab_order_details using(customer_id)
group by customer_id
order by num desc limit 1
)
union all
(
select
customer_id,
count(*) as num
from bab_customer right outer join bab_order_details using(customer_id)
group by customer_id
order by num asc limit 1
)
最初,我一直认为这会因为避免连接中间值而表现更好。但是,我没有看到任何性能提升。 (如果它更快,那么限制可以提升到某个任意数字,并且应用程序可以减少一些额外的值而不会损失大部分增加的性能)
但是,没有骰子。