shell脚本结合mysql语句处理对玩家进行排序

        实际项目中,遇到一个需求,需要先将所有数据库里的玩家进行排序,排序规则:每个分数段位选取前一百个玩家,放进排行榜数据表中,当遇到我们限定的分数上限值时,进行特殊处理,先选取大于上限值的一百个,叫做最强王者,然后在剩下的和等于上限值的当中,选取一百个,叫做至尊。

        例子:比如分数是  1   3   5   8   13    15   40    69   那么选择1-3  3-5  5-8一直到40-69的一百个,直接插入排序表。对于大于69的分数,先选取一百个叫做最强王者段位,在选剩下的人和等于69的人中再选取一百个叫做至尊。至尊可能没有人。

        解析:其实对于mysql语句很熟悉的人,可以写很多条mysql语句,放到.sql文件中,然后直接执行。但是我对于mysql并不是很熟悉,所以采用脚本相结合的方法。缺点很明显,mysql执行语句明显超多于正常使用mysql的语句。

#!/bin/bash

#从数据库找出各个段位,并根据经验值排序
./normal.sh  #通用处理的脚本(最大值以下)

#./bb.sh

#开始插入排行榜数据库排名信息
./insert.sh

echo "success"

normal.sh

先将定义的ar数组确定,因为要处理69以及大于69的特殊规则,所以干脆直接多加两个位置70以及无限大10000

#!/bin/bash



rm -f a b


ar=(1 3 5 8 13 15 40 69 70 10000)
numone=0
numtwo=0
for i in ${ar[*]};do
	if [ $numone -eq 0 ]
	then
		numone=$i
		continue;
	fi
	numtwo=$i
	mysql -uaaa -paaa -h***.***.***.*** tablename -e 'select CHARID from AUTOCHESSINFO where(TOTALEXP >= '$numone' && TOTALEXP < '$numtwo') order by TOTALEXP desc,CHARID;' > a
	sed -i '1d' a
	cat a >> b
	echo "=$numtwo" >>b
	numone=$i
done

insert.sh

这段shell脚本晦涩难懂,建议按照变量去看,而不是按照逻辑去看。每个变量的含义都很明确,看到他们的含义,就知道其实都是在为最强王者段位和至尊段位做特殊处理。

#!/bin/bash

(rm -f sepcial sepcialtwo)

rank=1
#每个段位人数
bigrank=100

num=1 #每个段位排名人数开始

flag=0      #顶部两个段位特殊处理
flagtwo=0   #王者段位
nosrot=0    #某一段位人数超过bigrank总限制 标志位

bigpos="=69"     #至尊九段开始
bigpostwo="=70"  #王者段位开始

while read -r line
do
	if [[ $line == $bigpos ]]  #判断王者段位
	then
		flag=1
		nosrot=0
		continue;
	fi

	if [ $nosrot -eq 1 ]       #判断是否插入数据库
	then
		if [[ $line != *=* ]] 
		then
			continue;
		else
			nosrot=0
		fi
	fi

	if [ $flag -eq 1 ]         #判断是否导入王者段位特殊处理文件
	then
		if [[ $line == $bigpostwo ]]
		then
			flagtwo=1    #王者段位
			continue;
		fi
		if [ $flagtwo -eq 1 ]  
		then
			echo $line >> sepcialtwo  #王者段位特殊文件
		else
			echo $line >> sepcial  #至尊九段特殊文件
		fi
		continue;
	fi
	
	if [[ $line != *=* ]]  #普通段位正常插入处理
	then
		if [ $num -gt $bigrank ]
		then
			nosrot=1
			continue;
		fi

		mysql -uaaa -paaa -h***.***.***.*** tablename -e 'insert into AUTOCHESSEXPRANK(RANKSEG,CHARID) values('$rank','$line');'
		echo "insert into AUTOCHESSEXPRANK: rank:$rank,id:$line"
		num=$(($num+1))
	else
		echo "$line"
		num=1
		rank=$(($rank+1))
		tmp=$(($rank % 10))
		if [ $tmp -eq 0 ]
		then
			rank=$(($rank+1))
		fi
	fi

done < b

sed -i '$d' sepcialtwo   #删掉最后一行
echo "$bigpos"

ranktmp=$(($rank+1))
rank=0
#处理special
num=1
flagenough=0
while read -r line
do	
	if [ $num -gt $bigrank ]     #特殊处理是否超限
	then
		if [ $flagenough -eq 1 ]
		then
			break;
		fi
		echo "$bigpostwo"
		flagenough=1
		num=1
		rank=$ranktmp
	fi
	
	mysql -uaaa -paaa -h***.***.***.*** tablename -e 'insert into AUTOCHESSEXPRANK(RANKSEG,CHARID) values('$rank','$line');'
	echo "insert into AUTOCHESSEXPRANK: rank:$rank,id:$line"
	num=$(($num+1))
done < sepcialtwo

if [ $flagenough -eq 1 ]
then
	if [ $num -le $bigrank ]
	then
		while read -r line
		do
			if [ $num -gt $bigrank ]
			then
				break;
			fi
			mysql -uaaa -paaa -h***.***.***.*** tablename -e 'insert into AUTOCHESSEXPRANK(RANKSEG,CHARID) values('$rank','$line');'
			echo "insert into AUTOCHESSEXPRANK: rank:$rank,id:$line"
			num=$(($num+1))
		done < sepcial
	fi
fi

        这种方法确实能实现,但是缺点太过于明显。其实有更好的方法,就是每个段位执行一句sql,在处理最后的69和大于69的人的时候,先选取大于69的人一百个叫做最强王者,其次选取大于等于69的人但是不在最强王者段位表里的人,一百个叫做至尊。这样就ok,思想很明确,思路很清晰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值