我有3张桌子:
table1: stores
columns:id(PK), name, visits
table2: categories
columns: id(PK), name
table3: cat_store
columns: store_id(FK), category_id(FK)
共有27个类别,每个商店至少有一个类别。 cat_store是联结表。 我想要实现的是按字母顺序获取所有类别的列表,并在每个类别名称下按名称列出前10个访问的商店。像这样:
categories.name1
stores.name1
stores.name2
....
stores.name10
categories.name2
stores.name1
stores.name2
....
stores.name10
...
categories.name27
stores.name1
stores.name2
....
stores.name10
目前我有一个包含所有类别名称的数组。然后在foreach循环中,我获得每个类别的商店。这意味着28次查询。
有没有办法用更少的查询实现这一目标?
提前致谢! 附:请原谅我的英语不好。
答案 0 :(得分:0)
你的英语很好。
您可以使用变量执行此操作,这可能是最有效的方法:
select cs.*
from (select c.name as catname, s.name as storename, s.visits,
@rn := if(@cid = c.id, @rn + 1, if(@cid := c.id, 1, 1)) as rn
from cat_store cs join
categories c
on cs.category_id = c.id join
stores s
on cs.store_id = s.id cross join
(select @rn := 0, @cid := 0) vars
order by c.id, visits desc
) cs
where rn <= 10;
注意:这会将类别作为单独的列而不是单独的行 - 这与结果集的表格格式一致。您可以使用rn = 1
逻辑轻松地在每个组的第一行中找到类别。