假设我有一个名为“users”的表,它有40行记录,每行都有字段:
id, firstname, group_id, login_count, stay_on_page_count
小组已经
administrator (1), manager (2), employee (3)
是否可以创建一个以这种方式对行进行排序和排序的查询
group _id stay_on_page_count login_count
========= ================== ===========
1 100mins 100
1 90mins 90
2 100mins 100
3 100mins 100
1 80mins 80
1 70mins 70
2 90mins 90
3 90mins 90
1 60mins 60
1 50mins 50
2 80mins 80
3 80mins 80
1 40mins 40
1 30mins 30
2 70mins 70
3 70mins 70
基本上我想使用查询结果创建一个4x4网格视图。伪代码可能是
SELECT all FROM user table and to group the result in to cluster of 4,
while each 4 should have ORDER BY group_id ASC as first priority (1,1,2,3)
AND stay_on_page_count ORDER BY DESC as second priority,
AND login_count ORDER BY DESC as last or third priority
我不知道伪代码是否解释得足够,但这是我能想出的唯一内容:)
如果它可能,那么它会牺牲性能吗? 有没有更好的方法来实现这个目标?
我正在使用Mysql和PHP(CakePHP 2.x)
谢谢
答案 0 :(得分:2)
一种方法(使用summarised
作为保存问题中列出的汇总值的表格):
select * from
(select s1.*,
@rank1:=@rank1+1 as rankcalc,
floor(@rank1/2) rankgroup,
@rank1%2 rankingroup
from (select @rank1:=1) r1
cross join
(select * from summarised where group_id=1 order by stay_on_page_count desc) s1
union all
select s2.*,
@rank2:=@rank2+1 as rankcalc,
@rank2 rankgroup,
2 rankingroup
from (select @rank2:=0) r2
cross join
(select * from summarised where group_id=2 order by stay_on_page_count desc) s2
union all
select s3.*,
@rank3:=@rank3+1 as rankcalc,
@rank3 rankgroup,
3 rankingroup
from (select @rank3:=0) r3
cross join
(select * from summarised where group_id=3 order by stay_on_page_count desc) s3
) sq order by rankgroup, rankingroup
SQLFiddle here。
请注意,此解决方案依赖于按子查询中指定的顺序进行计算的排序,而不是由优化程序覆盖 - 这应该适用于当前版本的MySQL,但可能无法在MariaDB中工作(开源MySQL的分支)或MySQL的未来版本。
答案 1 :(得分:0)
虽然这会产生你想要的顺序,但它却是一种强制和硬编码的努力。它使得一些假设如login_count始终在您列出的范围内。
SELECT group_ID, Stay_on_Page_count, Login_Count, myset
FROM (
SELECT group_ID, Stay_on_Page_Count, Login_Count, 1 as mySet
FROM USERS
WHERE (GROUP_ID=1 and Login_count >= 90) OR (group_ID in (2,3) and Login_Count=100)
UNION
SELECT group_ID, Stay_on_Page_Count, Login_Count, 2 as mySet
FROM USERS
WHERE (GROUP_ID=1 and Login_count Between 70 and 80)
OR (group_ID in (2,3) and Login_Count=90)
UNION
SELECT group_ID, Stay_on_Page_Count, Login_Count, 3 as mySet
FROM USERS
WHERE (GROUP_ID=1 and Login_count Between 50 and 60)
OR (group_ID in (2,3) and Login_Count=80)
UNION
SELECT group_ID, Stay_on_Page_Count, Login_Count, 4 as mySet
FROM USERS
WHERE (GROUP_ID=1 and Login_count Between 30 and 40)
OR (group_ID in (2,3) and Login_Count=70))
ORDER BY myset, group_ID, Login_count Desc