2011-01-13 101 views
1

我有一个数据库:复杂的SQL查询与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。

如果您有类别,产品和订单,并且希望按照每个类别的订单计数排名前十位的产品,那么类似的方法就是这样。

+1

如果您希望人们帮助您制作MySQL查询,您将需要包含您的表格定义。 – Dancrumb 2011-01-13 03:10:59

+0

如果您在最后使用类别,产品和订单示例,您可以想象一个标准表格定义。这同样是一个关于如何实现这一目标的概念性问题。我很高兴写下这个查询,我不知道如何在不使用union的情况下构建它。 – oak 2011-01-13 03:15:28

回答

1

此查询应该有效。

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 

的查询与此数据beentested:

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 

检查计数器列,然后将其降低到像2或3,只显示前每2或3的状态。