1、报错永远很迷糊
2、变量定义,前面不加@,即不能是@name---和sqlserver相反啊,有木有!!
mysql中变量定义用declare来定义一局部变量,该变量的使用范围只能在begin...end 块中使用,变量必须定义在复合语句的开头,并且是在其它语句之前,也可以同时申明多个变量,如果需要,可以使用default赋默认值。
3、where判断时,使用列取别名,有时候报错---
select id,first_name,last_name,salary,deptid did from employee where (select avg(salary) from employee where deptid = did) > 1800;
------------error: Unknown column 'did' in 'where clause'
------------在sqlserver中,报错:列名 'did' 无效。
个人猜测:先执行from employee where (select avg(salary) from employee where deptid = did) > 1800,造成did无法识别----参考后文《sql执行顺序》。
更正:
select id,first_name,last_name,salary,deptid from employee f where (select avg(salary) from employee where deptid=f.Deptid) > 1800;
奇怪的是,下面列别名用于having判断却没有问题(仅限于mysql。在sqlserver中,报错:列名 'did' 无效。)!!!---------疯了。
select id,first_name,last_name,salary,deptid pid from employee f where (select avg(salary) from employee group by deptid having deptid=pid) > 1800;
3.1 类似错误
delete from student2 where id not in (select min(id) from student2 group by code,name);
--------------错误码: 1093 You can't specify target table 'student2' for update in FROM clause
猜测可能删除操作,依赖于后面统计语句min(),而每次删除都使id改变(每删除一个记录,就update一次),这将导致统计语句结果min(id)也改变,min()前后不一致。
/*以下查询语句执行正确*/
/*select * from student2 where id not in(select min(id) from student2 group by name);*/
更正:
/**于是,我想先把分组的结果做成虚表,然后从虚表中选出结果,最后再将结果作为删除的条件数据----perfect*/
delete from student2 where id not in(select mid from (select min(id) mid from student2 group by name) as t);
select * from student2;
3.2 执行顺序
---参考后文《sql执行顺序》。
3.2.1
/*select tea_stu.teaID from tea_stu,teacher where tea_stu.teaID=teacher.teaID;*/
/*先select * from tea_stu,teacher ,得虚表A,然后在表A中实现where过滤条件,最后输出过滤后的A的指定值(列。。。)*/
3.2.2
select teacher.teaID from teacher join tea_stu on teacher.teaID=tea_stu.teaID;
/*select * from teacher join tea_stu ,得虚表A,然后在表A中实现on过滤条件,最后输出过滤后的A的指定值(列。。。)*/
4、delimiter // 取消默认的分号执行,采用//执行-----在定义存储过程、函数、触发器时基本都会用到。
记住用完了,改回来。
mysql:可以在某个数据库下创建
delimiter //
create PROCEDURE p()
begin
DECLARE a int;
set a=10;
select a;
end//
call p()//
图形界面中查询设计器中也要这么书写------可以认为最后还是一句一句在命令行中执行,而mysql遇到分号(默认执行符)时就会自动执行,导致begin..end被拆散,而报错
小心:
sqlserver:不可以在某个数据库下创建(第一句不能use db; why????)
create PROC p3
as
select * from student2
declare @a int
set @a=1
select @a
go
exec p3
5、新建表、数据库前,drop 类型 if exists 类型对象(限于mysql,不通用)
drop procedure if exists sp;
show procedure status;
对于临时表,语句需要改变。
6、实体,包括存储过程、函数、触发器,使用create drop
7、mysql好像不太支持数据库重命名???;sqlserver采用sp_renamedb。
8、mysql好像不太支持 select * into newtable from oldtable中的into操作。
select f.* into B from employee f ---------------错误码: 1327,Undeclared variable: B
但sqlserver没有问题
9、mysql支持的基本数据类型date,sqlserver2008才引入(之前使用datetime)
mysql: now() 等价于sqlserver: getdate()
10、mysql支持连续插入记录,sqlserver2005不支持,必须每条都用一个insert into
mysql: 列 id为identity,null填充它
insert into student2 values(null,'2005001','张三'),(null,'2005002','李四'),(null,'2005001','张三');
sqlserver2005:
insert into student2 values('2005001','张三');
insert into student2 values('2005002','李四');
注意:当id为identity时,插入数据,不需填充任何数据
insert into student2 values(null,'2005001','张三');
-----error:仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'student2'中的标识列指定显式值。
11、图形界面工具,点击“执行”
只有所有待执行语句都正确时,才会一一执行。有任何一个错误,所有语句都不会执行。
12、from后面基本上最多两张表(含虚表)
原因:from后紧接着的tables,是以笛卡尔乘积作为结果,然后再执行其它操作--如果table过多,笛卡尔乘积(列=各列之和,行= 各行累积)就很庞大!!
举例:
/**SELECT student.name from teacher ,student,tea_stu where student.age>12;*/
/*笛卡尔结果,远远超过SELECT student.name from student where student.age>12;*/
right---
select teacher.teaid,teacher.name,total
from teacher ,
(select tea_stu.teaid,count(*) total
from student,tea_stu
where student.stuid=tea_stu.stuid and student.age>12
group by tea_stu.teaid) as tea_stu2 /*所教的学生大于12岁的老师*/
where teacher.teaid=tea_stu2.teaid
and teacher.age<45;/*这些老师中小于45岁的*/
error---from teacher ,student,tea_stu的笛卡尔乘积结果符合where条件的比想象的多得多。
SELECT teacher.teaID,teacher.name, count(*) total from teacher ,student,tea_stu
where student.age>12
and student.stuID in
(SELECT stuID from tea_stu,teacher where tea_stu.teaID=teacher.teaID and teacher.age<45);
13、TODO 子查询 ,from...where的用法
子查询,按照sql执行顺序一步步小心推理,外层列的别名小心使用,因为它可能还没执行。
标准不统一,真费劲。