前几天吧系统从oracle往mysql上迁移,很多的语句是比较简单的,就是一些函数的修改如to-date等
但是也有几个比较棘手的,这里记录下
第一、row_number() over(partition by
首先要了解下oracle中这个函数的用法,看个例子
select t.*,row_number() over(partition by t.owner order by y.createDate desc) rn from test t
这个语句的意思就是,把test这个表的数据按照owner 分组并且给每个分组的里面的数据加上一个序列号,数据格式如下
id name owner createDate rn
1 aa 001 1
2 bb 001 2
3 cc 001 3
4 dd 002 1
5 ee 002 2
6 ff 003 1
数据搞得不太正规,但是应该能够看懂它的意思吧,
但是在mysql中是没有这个函数的于是乎,找啊找,总算找了个解决方法,如下
SELECT
heyf_tmp.*,
IF(@pdept=heyf_tmp.owner ,@rn:=@rn+1,@rn:=1) AS rn,
@pdept:=heyf_tmp.owner
FROM
(
SELECT
yv.*
FROM
test yv
ORDER BY
yv.owner ,
yv.createDate DESC
)
heyf_tmp ,
(
SELECT
@rn :=0 ,
@pdept := NULL ,
@rn:=0
)
aa
具体是什么意思,不是很清楚,不过先解决问题再说
第二、oracle树形查询
oracle树形查询现成的方法
select distinct t.id as id, t.name
from test t
start with id=‘’
connect by prior id = parentid
但是mysql中是没有这个方法的,于是只能自己定义函数或者过程,我这里用的是过程
如下
CREATE PROCEDURE Pro_GetTreeList`(in pid varchar(36))
begin
declare lev int;
set lev=1;
drop table if exists tmp1;
CREATE TABLE tmp1(id VARCHAR(40),name varchar(50),parentid varchar(40) ,levv INT);
INSERT tmp1 SELECT id,name,parent_id,1 FROM `test` WHERE parent_id=pid;
while row_count()>0
do set lev=lev+1;
INSERT tmp1 SELECT t.id,t.name,t.parent_id,lev from testt join tmp1 a on t.parent_id=a.id AND levv=lev-1;--查出子节点
end while ;
INSERT tmp1 SELECT id,name,parent_id,0 FROM test WHERE id=pid; --查出当前节点
end
这个存储过程应该都能看懂吧,就不做多解释了
第三 、函数中定义类似一维、二维数组,
oracle中可以直接定义的,如
return number is newList := NewList((1,2,3),(4,5,6));这样可以直接返回 return newList(1,2) 返回的就是2了,
但是mysql中却不能这样写的,不过也有这样的方法解决:
对于一维的来说,很简单,有函数的elt函数,可以直接return elt(index,'1','2','3'); 如果elt(3,'1','2','3') 这样返回的就是 3了,
不过对于二维的来说好像没有现成的函数用了,我的解决方法是改成个表来做,把数据录入到表中,然后去查表,这丫要给你也是可以实现
第四、 mysql中获取汉字的首个大写字母
mysql中遇到了这样的一个问题,网上找到了方法,转载地址://http://blog.csdn.net/lky5387/article/details/11973721
DROP FUNCTION IF EXISTS `getPY`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` FUNCTION `getPY`(in_string VARCHAR(65534)) RETURNS mediumtext CHARSET utf8
BEGIN
DECLARE tmp_str VARCHAR(65534) charset gbk DEFAULT '' ; #截取字符串,每次做截取后的字符串存放在该变量中,初始为函数参数in_string值
DECLARE tmp_len SMALLINT DEFAULT 0;#tmp_str的长度
DECLARE tmp_char VARCHAR(2) charset gbk DEFAULT '';#截取字符,每次 left(tmp_str,1) 返回值存放在该变量中
DECLARE tmp_rs VARCHAR(65534) charset gbk DEFAULT '';#结果字符串
DECLARE tmp_cc VARCHAR(2) charset gbk DEFAULT '';#拼音字符,存放单个汉字对应的拼音首字符
SET tmp_str = in_string;#初始化,将in_string赋给tmp_str
SET tmp_len = LENGTH(tmp_str);#初始化长度
WHILE tmp_len > 0 DO #如果被计算的tmp_str长度大于0则进入该while
SET tmp_char = LEFT(tmp_str,1);#获取tmp_str最左端的首个字符,注意这里是获取首个字符,该字符可能是汉字,也可能不是。
SET tmp_cc = tmp_char;#左端首个字符赋值给拼音字符
IF LENGTH(tmp_char)>1 THEN#判断左端首个字符是多字节还是单字节字符,要是多字节则认为是汉字且作以下拼音获取,要是单字节则不处理。
SELECT ELT(INTERVAL(CONV(HEX(tmp_char),16,10),0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7,0xBFA6,0xC0AC
,0xC2E8,0xC4C3,0xC5B6,0xC5BE,0xC6DA,0xC8BB,0xC8F6,0xCBFA,0xCDDA ,0xCEF4,0xD1B9,0xD4D1),
'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y','Z') INTO tmp_cc; #获得汉字拼音首字符
END IF;
SET tmp_rs = CONCAT(tmp_rs,tmp_cc);#将当前tmp_str左端首个字符拼音首字符与返回字符串拼接
SET tmp_str = SUBSTRING(tmp_str,2);#将tmp_str左端首字符去除
SET tmp_len = LENGTH(tmp_str);#计算当前字符串长度
END WHILE;
RETURN tmp_rs;#返回结果字符串
END;;
DELIMITER ;
第四、 图片clob的修改
系统中的功能是把图片存在blob字段中的,,原来用的是oracle,java中对应的字段是Object,但是mysql中如果这样做却不能独处图片,原因可能是因为在往Object中写数据时出错了,这个号解决,只要把java中对应字段的类型改成byte[] 就行了
第五、mysql中 group_concat 与 find_in_set 用法
在项目中遇到这样的需求,
表event中如下字段 表work中如下字段
id ename id wname eventid
1001 事件1 1 工作1 1001
1002 事件2 2 工作2 1001,1002
1003 事件3 3 工作3 1001,1003
现查询了一张work表数据,需要展示id name event名称,只用一个sql展示,
select wname, (select group_concat(ename) from event where find_in_set(id,eventid) ) as ename from work;
这一个sql就可以搞定,find_in_set 用法以逗号分隔开与id进行匹配,返回多条记录, group_concat为把展示的多行记录做成一列展示并以逗号拼接