创建方式:
SQL
CREATE PROCEDURE group
BEGIN
END
mysql要带参数 即使没有参数也要带括号
CREATE PROCEDURE `group`()
BEGIN
END
注释:
sql
--修改面积
mysql
#修改面积
每句结尾的分号
sql
update rooms set group_id=area.id
mysql
update rooms set group_id=area.id;
临时表的用法:
临时表有如下限制(所以脚本中的表都改用实体临时表):
在同一个query语句中,你只能查找一次临时表 否则会报错:
遇到的错误-----MySQL使用临时表 出现 “ERROR 1137 (HY000): Can't reopen table” 的异常 解决方法
sql
CREATE PROCEDURE [dbo].[spGetChildren]
@id AS int
AS
BEGIN
declare @temp table(tid int)
insert @temp select dept_id from department d where d.dept_id = @id
while @@rowcount > 0
insert @temp select d.dept_id from department as d inner join @temp as t
on d.up_dept_id = t.tid and d.dept_id not in(select tid from @temp)
DELETE FROM @temp WHERE tid=@id
select * from @temp
END
mysql
CREATE PROCEDURE spGetChildren(id int)
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS temp(tid int);
CREATE TEMPORARY TABLE IF NOT EXISTS temp1 (tid int);
CREATE TEMPORARY TABLE IF NOT EXISTS temp2 (tid int);
insert into temp select dept_id from department d where d.dept_id = id;
WHILE ROW_COUNT() > 0 DO
select * from temp;
delete from temp1;
delete from temp2;
insert into temp1 select tid from temp;
insert into temp2 select tid from temp;
insert temp select d.dept_id from department as d inner join temp1 as t
on d.up_dept_id = t.tid and d.dept_id not in (select tid from temp2);
END WHILE;
DELETE FROM temp WHERE tid=id;
select * from temp;
delete from temp;
END
日期加减:
sql
减
DATEADD(day,-1,GETDATE())
加
DATEADD(day,1,GETDATE())
mysql
减
date_sub(now(),interval 1 day)
加
date_add(now(),interval 1 day)
CONVERT
sql
CONVERT(date,'2013-12-23')
mysql
CONVERT('2013-12-23',date)
cast(rise as numeric(12))
mysl 中用 cast(rise as DECIMAL(12))
mysql中的cast和 convert 只能用以下类型 请自行判断转换:
这个类型 可以是以下值其中的 一个:
BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
select .... into ...
mysql中会报错 Undeclared variable: temp
mysql不支持select...into...语法,可以使用INSERT INTO ... SELECT .. 代替它。
ISNULL
sql
ISNULL(字段,0)
mysql
IFNULL(bd.ableFlag,0)
下面是 测试表与测试数据
-- 学生表
CREATE TABLE student (
SNO INT,
SNAME VARCHAR(10),
ICNO INT
);
-- 食堂IC卡表
CREATE TABLE IC (
ICNO INT,
ICNAME VARCHAR(10),
ICMoney INT
);
INSERT INTO student VALUES(1, '张三', 1 );
INSERT INTO student VALUES(2, '李四', 2 );
INSERT INTO student VALUES(3, '王五', NULL);
INSERT INTO IC VALUES(1, '张三', 500 );
INSERT INTO IC VALUES(2, '李四', 250 );
INSERT INTO IC VALUES(3, '赵老师', 600);
下面是 SQL Server 使用 full join 的结果
SELECT
student.SNO,
student.SNAME,
IC.ICNAME,
IC.ICMoney
FROM
student
FULL JOIN IC
ON (student.ICNO = IC.ICNO);
go
SNO SNAME ICNAME ICMoney
----------- ---------- ---------- -----------
1 张三 张三 500
2 李四 李四 250
3 王五 NULL NULL
NULL NULL 赵老师 600
(4 行受影响)
下面是 MySQL 不支持 的输出结果:
mysql> SELECT
-> student.SNO,
-> student.SNAME,
-> IC.ICNAME,
-> IC.ICMoney
-> FROM
-> student
-> FULL JOIN IC
-> ON (student.ICNO = IC.ICNO);
ERROR 1054 (42S22): Unknown column 'student.SNO' in 'field list'
下面是 MySQL 的 LEFT JOIN + UNION + RIGHT JOIN 的方式。
mysql> SELECT
-> student.SNO,
-> student.SNAME,
-> IC.ICNAME,
-> IC.ICMoney
-> FROM
-> student
-> LEFT JOIN IC
-> ON (student.ICNO = IC.ICNO)
-> UNION
-> SELECT
-> student.SNO,
-> student.SNAME,
-> IC.ICNAME,
-> IC.ICMoney
-> FROM
-> student
-> RIGHT JOIN IC
-> ON (student.ICNO = IC.ICNO);
+------+-------+--------+---------+
| SNO | SNAME | ICNAME | ICMoney |
+------+-------+--------+---------+
| 1 | 张三 | 张三 | 500 |
| 2 | 李四 | 李四 | 250 |
| 3 | 王五 | NULL | NULL |
| NULL | NULL | 赵老师 | 600 |
+------+-------+--------+---------+
4 rows in set (0.01 sec)
原文链接:
例子二:
01 求在A中不在B中的结果
SELECT A.customersid, '0' as IsOrder,'1' as IsBirth
FROM cs_nowbirthcust A left JOIN cs_precalloutcust B ON A.customersid = B.customersid
where B.customersid is null
11求在A中也在B中的结果
SELECT B.customersid, '1' as IsOrder,'1' as IsBirth
FROM cs_nowbirthcust A inner JOIN cs_precalloutcust B ON A.customersid = B.customersid
10求在不在A中在B中的结果
SELECT B.customersid, '1' as IsOrder,'0' as IsBirth
FROM cs_nowbirthcust A right JOIN cs_precalloutcust B ON A.customersid = B.customersid
where a.`customersid` is null
使用union all联合结果集合 01, 11, 10
即:
SELECT A.customersid, '0' as IsOrder,'1' as IsBirth
FROM cs_nowbirthcust A left JOIN cs_precalloutcust B ON A.customersid = B.customersid
where B.customersid is null
union all
SELECT A.customersid, '1' as IsOrder,'1' as IsBirth
FROM cs_nowbirthcust A inner JOIN cs_precalloutcust B ON A.customersid = B.customersid
union all
SELECT b.customersid, '1' as IsOrder,'0' as IsBirth
FROM cs_nowbirthcust A right JOIN cs_precalloutcust B ON A.customersid = B.customersid
where a.`customersid` is null
原文链接:
update t_p_rooms set t_p_totalpricegroup_id=total.id
from t_p_rooms rm,t_p_totalpricegroup total
where rm.t_p_totalpricegroup_id is null and
rm.totalprice>=total.down and rm.totalprice
MYSQL
update t_p_rooms rm
INNER JOIN t_p_totalpricegroup total
ON rm.t_p_totalpricegroup_id is null and
rm.totalprice>=total.down and rm.totalprice
mysql用变量做表名
@tablename
在sql中我们可以 自己拼凑变量用作表名
但mysql中不行。
mssql的解决方法是将整条sql语句作为变量,其中穿插变量作为表名,然后用sp_executesql调用该语句。
sql
SELECT COUNT(*) INTO @num_count FROM tbl_name WHERE rng = para_rng
AND north_latitude = para_north
AND bck_datetime = para_datetime
AND east_longitude = para_east;
mysql
SET tbl_name = CONCAT("20131226", tablename);
SET @STMT := CONCAT("SELECT COUNT(*) INTO @num_count FROM ", tbl_name
," WHERE rng = '", para_rng
,"' AND north_latitude = ", para_north
," AND bck_datetime = '", para_datetime
,"' AND east_longitude = ", para_east, ";");
PREPARE STMT FROM @STMT;
EXECUTE STMT;
参考链接:
mysql存储过程中用变量做表名row_number() over(partition by ...order by...)
sql
select t_p_rooms_keyid
,ROW_NUMBER() over(partition by t_p_baseinfo_id,t_p_building_id,t_p_batchinfo_id,rise order by t_p_rooms_keyid) as rank
from t_p_rooms
where rise is not null
mysql
select t_p_rooms_keyid,rank fromwhile ...begin....end 循环
sql
while a = 0
begin
exec dbo.Proc_RoomsBuildType @t_p_building_keyid;
fetch next from MyCursor into t_p_building_keyid;
end
mysql
while a = 0SET NOCOUNT ON
mysql中没找到具体用法 欢迎提供
游标的用法:
1.游标的定义:
游标(cursor)必须在声明处理程序之前被声明,并且变量和条件必须在声明游标或处理程序之前被声明。
也就是 放在begin 之后 与 处理程序之前是 ok的放在处理程序中间无法编译通过
2.@@FETCH_STATUS
sql
while @@FETCH_STATUS = = 0
begin
exec dbo.Proc_RoomsBuildType @t_p_building_keyid;
fetch next from MyCursor into t_p_building_keyid;
end
mysql中没有@@FETCH_STATUS系统变量 会出现 unknown system variable FETCH_STATUS 错误
mysql中的用法是给它定义一个结束标识
declare done int default 0;
#注意这句的顺序 不能放在 declare MyCursor curcor后面,否则会报错(ERROR 1337: Variable or condition declaration after cursor or handler declaration)
declare MyCursor cursor for
select t_p_building_id
from t_p_building
where t_p_buildingtype_id is null or t_p_buildingtype_id=1
order by t_p_building_keyid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
open MyCursor;
fetch next from MyCursor into t_p_building_keyid;
while done <> 1
do
call Proc_RoomsBuildType(t_p_building_keyid);
fetch next from MyCursor into t_p_building_keyid;
end while;
CLOSE MyCursor;
3.fecth into的值
FETCH NEXT FROM authors_cursor into a; //a是我们定义的变量 且不能跟 实体表中的字段同名 否则会fetch失败
这里有一个比较坑的地方,注意,变量的定义不要和你的select的列的键同名!不然,fetch into 会失败!
参考链接:
http://www.cnblogs.com/trying/p/3296793.html
spilt函数
在mysql中并没有split函数,需要自己写:
获取分割后的字符串个数的函数:
DELIMITER $$
CREATE DEFINER=`davy`@`%` FUNCTION `Split_getCount`(
f_string varchar(1000),f_delimiter varchar(5)
) RETURNS int(11)
BEGIN
return 1+(length(f_string) - length(replace(f_string,f_delimiter,'')));
END
DELIMITER $$
CREATE DEFINER=`davy`@`%` FUNCTION `Split_getString`(f_string varchar(1000),f_delimiter varchar(5),f_order int) RETURNS varchar(255) CHARSET utf8
BEGIN
declare result varchar(255) default '';
set result = reverse(substring_index(reverse(substring_index(f_string,f_delimiter,f_order)),f_delimiter,1));
return result;
END
用法例子如下:
create table IF NOT EXISTS InsertRsAndRi_temp
(
id int(11) auto_increment primary key,
singleVal nvarchar(1000)
);
truncate table InsertRsAndRi_temp;
set @count=Split_getCount(splitName_var,'、');
set @i=1;
while @i<=@count
do
set val = Split_getString(splitName_var,'、',i);
insert into InsertRsAndRi_temp set singleVal=val;
set i = i+1;
end while;
mysql funtion自定义函数返回table
在sql中可以在funtion中直接返回table
但在mysql中不可以 那如果我们要用table怎么办呢 只能在funtion中把值返回回来 再构造一个table 具体用法参考上面Split的函数的 用法例子。
IF(...) begin.... end
改为: IF() then..elseif () then ..END IF
注意 if else if 与 if elseif的区别!
charindex
查找字符串的位置 在mysql中用locate
将某一字段所有值去重过后拼接为一个字段
sql
dbo.SUMTEXT(distinct t_p_roomusetype_id)
mysql
GROUP_CONCAT函数 注意事项 字段为int时要先转换成char
语法:
GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name ...]] [SEPARATOR str_val])
1.例如:
SELECT student_id, GROUP_CONCAT(courses_id) AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id;
+------------+---------+
| student_id | courses |
+------------+---------+
| 2 | 3,4,5 |
+------------+---------+
这 就不需要用php循环了
$row = $pdo->query("SELECT student_id, GROUP_CONCAT(courses_id) AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id");
$result = explode(',', $row['courses']);
2.当然分隔符还可以自定义,默认是以“,”作为分隔符,若要改为“|||”,则使用SEPARATOR来指定,例如:
SELECT student_id, GROUP_CONCAT(courses_id SEPARATOR '|||') AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id;
+------------+---------+
| student_id | courses |
+------------+---------+
| 2 | 3|||4|||5 |
+------------+---------+
3.除此之外,还可以对这个组的值来进行排序再连接成字符串,例如按courses_id降序来排:
SELECT student_id, GROUP_CONCAT(courses_id ORDER BY courses_id DESC) AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id;
+------------+---------+
| student_id | courses |
+------------+---------+
| 2 | 5,4,3 |
+------------+---------+
4.需要注意的:
a.int字段的连接陷阱
原文链接:
关于mysql函数GROUP_CONCAT
merge ...using...when ...update set...
sql
merge t_p_rooms
using InsertBdRm_moniter_temp
on t_p_rooms.t_p_rooms_keyid = InsertBdRm_moniter_temp.t_p_rooms_keyid
when MATCHED and ((t_p_rooms.roomstate in(1,2) or t_p_rooms.roomstate is null) and (InsertBdRm_moniter_temp.roomstate in (3,4,5,6)))
then update SET t_p_rooms.roomstate = InsertBdRm_moniter_temp.roomstate,
t_p_rooms.backflg_b = 0,
t_p_rooms.salestate = 1,
t_p_rooms.roomarea = case when InsertBdRm_moniter_temp.roomarea is null then t_p_rooms.roomarea else InsertBdRm_moniter_temp.roomarea end,
t_p_rooms.bakDate_b = null;
mysql
replace into t_p_rooms (roomstate,backflg_b,alestate,roomarea,bakDate_b)
select roomstate,0,1,case when InsertBdRm_moniter_temp.roomarea is null then t_p_rooms.roomarea else InsertBdRm_moniter_temp.roomarea end,null from InsertBdRm_moniter_temp
where t_p_rooms.t_p_rooms_keyid = InsertBdRm_moniter_temp.t_p_rooms_keyid
and ((t_p_rooms.roomstate in(1,2) or t_p_rooms.roomstate is null) and (InsertBdRm_moniter_temp.roomstate in (3,4,5,6)));
参考资料:
MySQL中的insert ignore into, replace into等的一些用法总结
http://www.2cto.com/database/201108/99073.html
MySQL Replace INTO的使用(转载)
http://wensong.iteye.com/blog/677919
MsSQL中類似MySQL replace into的指令
http://www.2cto.com/database/201309/240856.html
not unique table/alias tablea
则 SQL 语句中出现了非唯一的表或别名。
解决方法:
1、请检查出现问题位置的 SQL 语句中是否使用了相同的表名,或是定义了相同的表别名。
2、检查 SELECT 语句中要查询的字段名是不是定义重复,或者没有定义。
检查有没有如下语句:
update tablea innser join tablea on id in (1,2,3) set name='x';