用户自定义变量使用:
- 优化排名语句
通过变量复制,快速实现类似行号功能
SET @rownum :=0 ;
SELECT school_id , school_name , @rownum :=@rownum+1 AS rownum
FROM base_school WHERE school_id<0
LIMIT 10 ;
-- sql 排名
SET @currcnt :=0 ,@precnt :=0, @rank :=0 ;
SELECT school_id ,
@currcnt := cnt AS cnt ,
@rank := if(@precnt <> @currcnt , @rank+1 ,@rank ) AS rank ,
@precnt := @currcnt dusum
FROM
(
SELECT school_id , COUNT(*) AS cnt
FROM base_student
GROUP BY school_id
ORDER BY cnt DESC
) de ;
- 避免重复查询刚更新的数据
- 统计更新插入的数量
-- SQL 统计更新写入数量
INSERT INTO base_terminal_key( terminal_key,city_code ,exam_area_code)
VALUES('11cvt8ib8g' , '05' ,'0502'),('11cXX8ib8g' , '05' ,'0502'),('1cvDt8ib8g' , '05' ,'0502')
ON DUPLICATE KEY UPDATE
terminal_key =VALUES(terminal_key) + ( 0* (@ct :=@ct+1)) ;
- 确定取值顺序
参考地址: http://mysqldump.azundris.com/archives/86-Down-the-dirty-road.html
UNION 使用
假设需要编写union来实现第一个查询作为分支查询来先执行,找到了就跳过第二个分支,例如热用户数据得查询。
-- 步骤3:生成顺序码,其中考生按照学校人数多到少、班级人数多到少、学校id、班级编号、考籍号 进行排序
update base_examination_arrange_temp_room a
inner join (
select sr.id ,sr.stud_exam_code, sr.school_cnt, sr.class_cnt,
if(@exam_place_code != sr.exam_place_code or @syllabus_code != sr.syllabus_code , @num := 1, @num := @num+1) num ,
@exam_place_code := sr.exam_place_code exam_place_code,
@syllabus_code := sr.syllabus_code syllabus_code
from (
select a1.id , a1.exam_place_code, a1.syllabus_code, a1.stud_exam_code, a1.class_code, a2.school_cnt, a3.class_cnt
from base_examination_arrange_temp_room a1
left join (
select school_id, exam_place_code, syllabus_code, count(school_id) school_cnt
from base_examination_arrange_temp_room
where examination_code=examinationCode and exam_area_code=examAreaCode
group by school_id, exam_place_code, syllabus_code
) a2 on a2.school_id=a1.school_id and a2.exam_place_code=a1.exam_place_code and a2.syllabus_code=a1.syllabus_code
left join (
select school_id, exam_place_code, syllabus_code, class_code, count(stud_exam_code) class_cnt
from base_examination_arrange_temp_room
where examination_code=examinationCode and exam_area_code=examAreaCode
group by school_id,exam_place_code,syllabus_code,class_code
) a3 on a3.school_id=a1.school_id and a3.exam_place_code=a1.exam_place_code and a3.syllabus_code=a1.syllabus_code and a3.class_code=a1.class_code
where a1.examination_code=examinationCode and a1.exam_area_code=examAreaCode
order by a1.exam_place_code, a1.syllabus_code, a2.school_cnt desc, a3.class_cnt desc, a1.class_code, a1.stud_exam_code
) sr,
(select @exam_place_code := '', @syllabus_code := '', @num := 0) b
) tp
set a.order_num = tp.num
where a.id=tp.id ;
-- 步骤4:按照考点+科目,把顺序码 分4段
update base_examination_arrange_temp_room a
inner join (
select a.id, a.exam_place_code, a.syllabus_code, a.stud_exam_code,
t.maxOrderNum,
case
when a.order_num <= t.divid1 then 1
when a.order_num <= t.divid2 then 2
when a.order_num <= t.divid3 then 3
else 4
end section_flag
from (select * from base_examination_arrange_temp_room where examination_code = examinationCode and exam_area_code = examAreaCode) a
left join (
select tt.*,
if(mod(tt.maxOrderNum, 4)!=0, tt.maxOrderNum*0.25+1, tt.maxOrderNum*0.25) divid1,
if(mod(tt.maxOrderNum, 4)=3, tt.maxOrderNum*0.5+1, if(tt.maxOrderNum=5, tt.maxOrderNum*0.5+1, tt.maxOrderNum*0.5)) divid2,
if(mod(tt.maxOrderNum, 4)>1, tt.maxOrderNum*0.75+1, if(tt.maxOrderNum=5, tt.maxOrderNum*0.75+1, tt.maxOrderNum*0.75)) divid3
from (
select exam_place_code, syllabus_code, max(order_num) maxOrderNum
from base_examination_arrange_temp_room
where examination_code = examinationCode and exam_area_code = examAreaCode
group by exam_place_code, syllabus_code
) tt
) t on t.exam_place_code = a.exam_place_code and t.syllabus_code = a.syllabus_code
)tp
set a.section_flag = tp.section_flag, random_num=floor(1 + rand() * tp.maxOrderNum)
where a.id = tp.id;
-- 步骤5:更新座位号
-- 5.1 更新奇数座位
update base_examination_arrange_temp_room a
inner join (
select id,
if(@exam_place_code != a.exam_place_code or @syllabus_code != a.syllabus_code, @rn:=1, @rn := @rn+1) rn,
if(@exam_place_code != a.exam_place_code or @syllabus_code != a.syllabus_code, @room:=1, if(mod(@rn-1, 15) = 0, @room := @room+1, @room)) room,
if(@exam_place_code != a.exam_place_code or @syllabus_code != a.syllabus_code, @seat := 1, if(mod(@rn-1, 15) = 0, @seat := 1, @seat := @seat+2)) seat,
@exam_place_code := a.exam_place_code exam_place_code,
@syllabus_code := a.syllabus_code syllabus_code
from base_examination_arrange_temp_room a,
(select @rn:=0, @room:=1, @seat:=-1, @exam_place_code := '', @syllabus_code := '') b
where a.examination_code = examinationCode and a.exam_area_code = examAreaCode and a.section_flag in(1, 2)
order by a.exam_place_code, a.syllabus_code, a.section_flag, a.random_num
) b
set a.room_no = b.room, a.seat_no =b.seat
where a.examination_code = examinationCode and a.exam_area_code = examAreaCode and a.id = b.id;
if(recode = '-8') then
set recode = '-84';
set errMsg = '编排奇数座位号时失败。';
select recode, errMsg;
leave label;
end if;
-- 5.2 更新偶数座位
update base_examination_arrange_temp_room a
inner join (
select id,
if(@exam_place_code != a.exam_place_code or @syllabus_code != a.syllabus_code, @rn:=1, @rn := @rn+1) rn,
if(@exam_place_code != a.exam_place_code or @syllabus_code != a.syllabus_code, @room:=1, if(mod(@rn-1, 15) = 0, @room := @room+1, @room)) room,
if(@exam_place_code != a.exam_place_code or @syllabus_code != a.syllabus_code, @seat := 2, if(mod(@rn-1, 15) = 0, @seat := 2, @seat := @seat+2)) seat,
@exam_place_code := a.exam_place_code exam_place_code,
@syllabus_code := a.syllabus_code syllabus_code
from base_examination_arrange_temp_room a,
(select @rn:=0, @room:=1, @seat:=0, @exam_place_code := '', @syllabus_code := '') b
where a.examination_code = examinationCode and a.exam_area_code = examAreaCode and a.section_flag in( 3, 4)
order by a.exam_place_code, a.syllabus_code, a.section_flag, a.random_num
) b
set a.room_no = b.room, a.seat_no =b.seat
where a.examination_code = examinationCode and a.exam_area_code = examAreaCode and a.id = b.id;
if(recode = '-8') then
set recode = '-85';
set errMsg = '编排偶数座位号时失败。';
select recode, errMsg;
leave label;
end if;
-- 步骤6:更新小语种的考场号
update base_examination_arrange_temp_room a
inner join (
select t1.exam_place_code,
t1.syllabus_code foreign_code,
t1.cnt,
if(@exam_place_code != t1.exam_place_code, @total_cnt:=0, if(t1.syllabus_code='31', @total_cnt:=0, @total_cnt:= @total_cnt + @cnt)) total_cnt,
@exam_place_code := t1.exam_place_code,
@cnt := t1.cnt
from (
select a.exam_place_code, a.syllabus_code, count(distinct b.room_no) cnt
from (
select p.exam_place_code , sy.syllabus_code
from base_examination_place p, (select syllabus_code from base_syllabus where syllabus_code in ('31' ,'32', '33', '34', '35', '36')) sy
where p.examination_code=examinationCode and p.exam_area_code=examAreaCode
) a
left join (
select *
from base_examination_arrange_temp_room
where exam_area_code=examAreaCode
and examination_code=examinationCode
and syllabus_code in ('31', '32', '33', '34', '35', '36')
) b ON a.exam_place_code=b.exam_place_code and a.syllabus_code=b.syllabus_code
group by a.exam_place_code, a.syllabus_code
) t1, (select @cnt:=0, @total_cnt:=0, @exam_place_code:='' ) t2
) b
set a.room_no = a.room_no + b.total_cnt
where a.examination_code = examinationCode
and a.exam_area_code = examAreaCode
and a.examination_code=examinationCode
and a.syllabus_code in ('32', '33', '34', '35', '36')
and a.exam_place_code=b.exam_place_code
and a.syllabus_code=b.foreign_code;