[英]Complex SQL Query with MySQL?
我有一个数据库:
[business] must have a [location]
[location] may have many [business]
[location] may have many [postcode]
[postcode] may be for many [location]
[postcode] must have a [state]
我希望查询返回每个州的业务计数最高的10个位置。
为了更有意义,它可能会出来:
Western Australia
- perth
- bunbury
- etc. up to 10
(即,珀斯在西澳大利亚州列出的企业最多)
Victoria
- melbourne
- st kilda
- etc. up to 10
等等。
我希望在不使用UNION的情况下实现这一目标。 我有一段时间没有做复杂的SQL了,这伤了我的头。
我正在使用MySQL。
如果您具有类别,产品和订单,并且希望按每个类别的订单数来排名前十位的产品,则可以采用类似的方法。
此查询应该工作。
select * from (
select a.state, a.location_id, C,
@n:=case when @s=a.state then @n+1 else 1 end counter,
@s:=a.state
from (select @s:=null) b, (
select pc.state, b.location_id, COUNT(b.location_id) C
from postcode pc
inner join location_postcode lp on lp.postcode_id=pc.id
inner join business b on b.location_id=lp.location_id
group by pc.state, b.location_id
order by pc.state, C desc
) a
) c
where counter <= 10
我使用了易于理解的字段名称,假设这些表以规定的关系存在:
business M-1 location
location M-M postcode
(expands to) => location 1-M location_postcode M-1 postcode
postcode M-1 state
查询已使用以下数据进行了测试:
create table business (location_id int);
insert into business select floor(rand()*10);
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
create table location_postcode (location_id int, postcode_id int);
insert into location_postcode select 1,1;
insert into location_postcode select 2,1;
insert into location_postcode select 3,1;
insert into location_postcode select 4,2;
insert into location_postcode select 5,1;
insert into location_postcode select 5,2;
insert into location_postcode select 6,1;
insert into location_postcode select 6,3;
insert into location_postcode select 7,1;
insert into location_postcode select 7,4;
insert into location_postcode select 8,5;
insert into location_postcode select 9,6;
insert into location_postcode select 10,7;
create table postcode (id int, state int);
insert into postcode select 1,1;
insert into postcode select 2,2;
insert into postcode select 3,3;
insert into postcode select 4,4;
insert into postcode select 5,4;
insert into postcode select 6,5;
insert into postcode select 7,5;
这并不能为每个“前10名”创建足够的记录,但是您将看到COUNTER列的排名正确。 要查看它是否适用于此较小的数据集,请首先将该过滤器留在此处
where counter <= 10
检查COUNTER列,然后将其减少为2或3,仅显示每个州的前2或3位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.