之前用mysql只是简单的复制粘贴,这次写一个相对复杂的sql总是出错,拓展看了下相关内容,惊人的发现我有这么多不知道的,这些你知道吗?
之所以引出sql书写顺序和执行顺序,源于具体要解决的问题是:
一个账号对应多个角色,每个角色都有等级,需要查询每一个账号下等级最大的那个角色id,且最大等级大于20?
错误方案:
select char_id ,level from tbl_char_level l,
tbl_char c where l.char_id = c.char_id order by level desc group by
user_id having level>= 20;
只能group by在前,order by在后
错误方案:用max时,引出另一个问题:
select max(level) as max_level, l.char_id, user_id from
char_level l, tbl_char
c where l.char_id=c.char_id group by(user_id) having max_level >=
10;
这里的max_level对应的char_id,并不是它对应的那个id。max只负责取最大的level,但是并不负责取出
max_level对应的char_id
正确解决方案--子查询:
select char_id
(
select char_id ,level from tbl_char_level l,
tbl_char c where l.char_id = c.char_id order by level desc
)
group by user_id having level
>= 20;
having处理group by分完组后,每组里的具体行信息
Select查询的语句顺序:
Select … from tbl1, tbl2 where ….group by … having ……order by
(asc | desc )
执行顺序:
1. from:对from子句中前两个表执行笛卡尔积生成虚拟表vt1
2. on:对vt1应用on筛选只有满足为真的行才被插入vt2
3. outer join:如果指定了outer
join保留表中未找到的行将作为外部行添加到v2生成vt3,如果from包含两个以上表,则对上一个联结生成的结果表和喜爱一个表重复执行步骤1和2直到结束
4. where:对vt3应用where筛选器只有使为true的行才被插入vt4
5. group by:按group by子句中的列列表对vt4中的行分组生成vt5
6. having:对vt5应用having筛选器只有使为true的组才插入vt6
7. select:处理select列产生vt7
8. distinct:将重复的行从vt7中去除产生vt8
9. order by:将vt8的行按order by子句中的列排序生成vt9