二、常用SQL: 1.建表前检查语句: MySQL的: drop table if exists 表名; SQL Server的: IF EXISTS (SELECT name FROM sysobjects WHERE name = ‘表名‘ AND type = ‘U‘) DROP TABLE 表名; Oracle的: create or replace table 表名 ...; -- 直接写建表语句
2.建表语句: create table 表名(memid int , points numeric(10,1) default 0, primary key (`memid`, `courseid`), FOREIGN KEY (`memid`) REFERENCES 表名2 (`memid`) on delete cascade on update cascade , CHECK ( points>=0 and points<=100 ) ); 3.复制表: CREATE TABLE 新表名 AS SELECT * FROM 旧表名; -- 仅复制数据,没复制表结构(自增主键等不会复制) CREATE TABLE 新表名 like 旧表名; -- 使用旧表创建新表,复制表结构(数据不会复制) 4.插入语句: INSERT INTO 表名(id,name,price,vend_name) VALUES(11,‘TV‘,222,‘US‘),(22,‘ss‘,12.22,‘kk‘); INSERT INTO 表名(id,name,price,vend_name) SELECT id,name,price,vend FROM 表名2; 5.更新语句: UPDATE 表名 SET column_name = expression, prod_name = ‘NEWCOMPUTER‘ [WHERE]; UPDATE 表1, 表2 SET 表2.column_name = expression, 表1.prod_name = ‘NEWCOMPUTER‘ [WHERE]; 6.删除语句: DELETE FROM 表名 WHERE search_conditions;
7.清空表格: TRUNCATE TABLE 表名; 8.修改表结构 修改字段: ALTER TABLE 表名 Modify col_name varchar(100); 添加字段: ALTER TABLE 表名 Add col_name varchar(100) default NULL COMMENT ‘匯款帳號或者匯款人‘ after col_name0; 减少字段: Alter Table 表名 Drop (column [,column]…); 添加约束: Alter TABLE 表名 Add FOREIGN KEY(column1) REFERENCES 表名2(column2); -- 添加非空约束时,要用Modify语句 删除约束: ALTER TABLE 表名 Drop FOREIGN KEY 表名_ibfk_1; Alter Table 表名 Drop CONSTRAINT column; 添加主键: Alter table 表名 add primary key(col); 删除主键: Alter table 表名 drop primary key(col); 唯一约束: ALTER [IGNORE] TABLE 表名 ADD UNIQUE INDEX (column [,column]…); -- IGNORE:删除重复; 没这个则重复时报错 9.创建索引: create [unique] index 索引名 on 表名(column [,column]…); 删除索引: drop index 索引名; 10.创建视图:create view 视图名 as select statement; 删除视图:drop view 视图名;
四、兼顾各数据库的 SQL 语句 1.自增列: Oracle: 建立 Sequence MySQL: create table test_t(id int primary key AUTO_INCREMENT, name varchar(80)); -- AUTO_INCREMENT 是自增关键字 SQL Server: create table test_t(id int primary key identity(1,1), name varchar(80)); -- identity(1,1) 是自增函数 access: create table test_t(id Integer primary key Counter(1,1), name varchar(80));
通用的: 使用表自身的自增列的最大值+1,如: insert into test_t(id, name) values((select nvl(max(id),0)+1 from test_t),‘holer‘); -- 这里 id 是表的自增列
2.伪列(序号): SELECT (SELECT Count(表名.aa) AS AutoNum FROM xlh WHERE (表名.aa <= 表名_tem.aa)) AS 序号, 表名.aa FROM 表名 AS 表名_tem INNER JOIN 表名 ON 表名_tem.aa=表名.aa ORDER BY 表名.aa;
Rownum:纬列。内存里排序的前N个。 在where语句中,可以用=1,和<=N 或 <N;但不能用=N 或 >N。 因为这是内存读取,没有1就丢弃再新建1。只能从1开始。需要从中间开始时,需二重子rownum语句需取别名。 经典应用: Top-n Analysis (求前N名或最后N名) Select [查询列表], Rownum From (Select [查询列表(要对应)] From 表 Order by Top-N_字段) Where Rownum <= N -- 不写这行则全部显示并排名。 SQL server的用法: Select top N 查询列表 From 表 Order by Top-N_字段
分页显示: --取工资第5~10名的员工(二重子rownum语句,取别名) select * From ( select id,last_name,salary,Rownum rn From (Select id,last_name,salary from s_emp order by salary desc) where rownum <= 10) where rn between 5 and 10;
三、常用简单语句: clear screen:清屏 edit:编辑刚才的一句。 desc/describe:(列出所有列名称) 用法: DESCRIBE [schema.]object[@db_link] dual:亚表(虚表),临时用。如:desc dual;/from dual; rollback:回溯,回溯到上次操作前的状态,把这次事务操作作废,只有一次(DDL和DCL语句会自动提交,不能回溯)。 可以用commit语句提交,这样就回溯不回了。 set pause on\off :设置分屏(设置不分屏) set pause "please put an enter key" 且 set pause on:设置带有提示的分屏 oerr ora 904 :查看错误 set head off :去掉表头 set feed off :去掉表尾 保存在oracle数据库中的所有操作细节: spool oracleday01.txt :开始记录 spool off :开始保存细节 SQL server的变量: 申明变量: declare @i int 设变量值: set @i=0 DECLARE @sql NVARCHAR(4000) SET @sql = ‘SELECT MEMID, NAME‘ SET @sql = @sql + ‘, ISNULL(STR(AVG(S.POINTS)), ‘‘0‘‘) AS ‘‘平均成绩‘‘ ‘ SET @sql = @sql + ‘ FROM TB_MEMBER ‘ PRINT @sql EXEC(@sql) update 表名 set 字段名=@i,@i=@i+1 --递增效果 另一递增效果:identity(1,1) --前参数是从多少开始,后参数是增量
四、SELECT语句:选择操作、投影操作。 select:从一个或多个表中检索一个或多个数据列。包含信息:想选择什么表,从什么地方选择。必须要有From子句。(最常用) 当从多张表里查询的时候,会产生笛卡尔积;可用条件过滤它。 当两个表有相同字段时必须加前缀,列名前需加表名和“.”,如“s_emp.id”。 1、用法:SELECT columns,prod2,prod3<列> FROM Table1,table2<表名> 分号结束 如: select id from s_emp; select last_name,name from s_emp,s_dept where s_emp.dept_id=s_dept.id;--列表每人所在部门 SELECT * FROM Products; --检索所有列。 数据太多时,最好别使用上句,会使DBMS降低检索和应用程序的性能。(*通配符) 2、对数据类型的列(字段)可进行运算(如加减乘除)。 3、对列起别名:有直接起别名,加AS起别名,用双引号起别名等三种方法 (单引号,引起字符串;双引号,引起别名。起别名有符号,或者区分大小写时,必须用双引号) 多表查询时,可给表起别名。(给列起别名,列<空格>列别名;给表起别名,表<空格>表别名;)。 如:Select first_name EMPLOYEES, 12*(salary+100) AS MONEY, manager_id "ID1" From s_emp E; 4、字段的拼接,可用双竖线(双竖线只能用于select语句里)。不同的DBMS可能使用不同的操作符;拼接的字段同样可以起别名。 如:Select first_name ||‘ ‘|| last_name || ‘, ‘|| title "Employees" From s_emp;
排他锁:Select id,salary From s_emp where id=1 For Update; 可以阻止他人并发的修改,直到你解锁。 如果已有锁则自动退出:Select id,salary From s_emp where id=1 For Update NoWait; FOR UPDATE :可以再加 OF 精确到某格。如: ... For Update OF salary ... 注意要解锁。
五、ORDER BY 子句,排序 Order by:按某排序列表(默认升序 asc, 由低到高; 可加 desc,改成降序由高到低) 检索返回数据的顺序没有特殊意义,为了明确地排序用 SELECT 语句检索出的数据,可使用 ORDER BY 子句。 ORDER BY 子句取一个或多个列的名字。 对空值,按无穷大处理(升序中,空值排最后;降序中排最前)。 1、用法:Select prod_id,prod_price,prod_name From Products Order By prod_price,prod_name; (从左到右执行排序,先排price) ORDER BY子句中使用的列将是为显示所选择的列,但是实际上并不一定要这样,用非检索的列排序数据是完全合法的。 为了按多个列排序,列名之间用逗号分开。 2、支持按相对列位置进行排序。位置从1开始。 输入 SELECT prod_id,prod_price,prod_name FROM Products ORDER BY 2,3 --(2指price,3指name) 3、升序、降序。默认是升序(asc,从小到大排序),想降序时用desc。 如:SELECT prod_id,prod_price,prod_name FROM Products ORDER BY prod_price DESC; 注意:DESC 关键字只应用到直接位于其前面的列名。如果想在多个列上进行排序,必须对每个列指定DESC关键字。 升序是默认的,可不写,但降序必须写。
六、WHERE子句,选择、过滤 其后只能跟逻辑语句,返回值只有ture或false 如: select last_name,salary from s_emp where salary=1000;--找出工资1000的人
between…and… :在两者之间。(BETWEEN 小值 AND 大值) NOT between ... and ... :指定不包含的范围。 如:select last_name,salary from s_emp where salary between 1000 and 1500; --工资1000到1500的人,包括1000和1500。
in(列表):在列表里面的。 in的括号里可包含次查询,即select子句 如:select last_name,dept_id from s_emp where dept_id in(41,42);第41、42部门的人
like : 包含某内容的。模糊查询 可以利用通配符创建比较特定数据的搜索模式,通配符只能用于文本,非文本数据类型不能使用通配符。 通配符在搜索模式中任意位置使用,并且可以使用多个通配符。 通配符%表示任何字符出现任意次数;还能代表搜索模式中给定位置的0个或多个字符。下划线匹配单个任意字符。 如:select table_name from user_tables where table_name like ‘S\_%‘ escape‘\‘; ‘ 找出“S_“开头的,由于下划线有任意字符的含义,故需另外定义转移符。 但习惯用“\”,为方便其它程序员阅读和检测,一般不改用其它的。 like ‘M%‘:M开头的 like ‘_a%‘:第二个字符是a的 like ‘%a%‘所有含a的 (“_”表示一个任意字符;“%”表示任意多个任意字符。) 如果将值与串类型的进行比较,则需要限定引号;用来与数值列进行比较时,不用引号。
is null:是空。(NULL表示不包含值。与空格、0是不同的。) 如:SELECT prod_name,prod_price FROM Products WHERE prod_price IS NULL;
and:条件与 如 SELECT prod_id,prod_price,prod_name FROM Products WHERE prod_price<4 AND vend_id=‘DELL’ or:条件或 (注: and 的优先级比 or 更高,改变优先级可用括号) 如 SELECT prod_id,prod_price,prod_name FROM Products WHERE prod_price<4 OR vend_id=‘DELL’ not:条件非。否定它之后所跟的任何条件 否定的SQL 比较运算符: NOT BETWEEN; NOT IN; NOT LIKE; IS NOT NULL: (注意,按英语习惯用 is not,而不是 not is) NOT 与 IN 在一起使用时,NOT 是找出与条件列表不匹配的行。 IN 列表里有 NULL 时不处理,不影响结果;用 NOT IN 时,有 NULL 则出错,必须排除空值再运算。 in :选择列表的条件 使用IN操作符的优点: 在长的选项清单时,语法直观; 计算的次序容易管理; 比 OR 操作符清单执行更快;最大优点是可以包含其它 SELECT 语句,使用能够动态地建立 WHERE 子句。 如 SELECT prod_id,prod_price,prod_name FROM Products WHERE vend_id IN(‘DELL’,’RBER’,’TTSR’); SELECT au_name FROM authors WHERE au_id NOT IN (SELECT au_id FROM titleauthors WHERE royaltyshare < .50); #找出版税不小于50%的作者.
NVL:处理空值,把空值转化为指定值。可转化为日期、字符、数值等三种(注意:转化时,两参数必须要同类型) 在SQL server 里用"ISNULL(需转的数据,转成什么)"函数代替。 遇到数值要把空转换成字符串的,需先把数值转成字符串类型。 如:NVL(date, ‘01-JAN-95‘) NVL(title,‘NO Title Yet‘) NVL(salary,0) 错误写法: Select last_name,title,salary*commission_pct/100 COMM From s_emp;--没提成的人没法显示工资 正确写法: Select last_name,title,salary*NVL(commission_pct,0)/100 COMM From s_emp;--把提成是空值的转化为0 注意:在oracle中的 NVL ,在 SQL server 中用 ISNULL。格式相同。
DISTINCT:过滤重复 把重复的行过滤掉;多个字段组合时,只排除组合重复的。 DISTINCT必须使用列名前,不能使用计算或者表达式。 所有的聚合函数都可以使用。如果指定列名,则DISTINCT只能用于COUNT(列名),DISTINCT不能用于COUNT(*)。 如:Select Distinct name From s_dept; Select Distinct dept_id,title From s_emp; 注意:Distinct 配合字段使用时,无法在字段列表里指定非唯一的单元或运算值。配合聚合函数使用时,需把 distinct 放到聚合函数的括号中,而仅对此函数有效。
文本处理: TRIM()/LTRIM()/RTIRM():去空格。只能去掉头和尾的空格,中间的不理。 trim(‘ heo Are fdou ‘) --> heo Are fdou 输入:select trim(‘ heo Are fdou ‘) from dual; -->:heo Are fdou LOWER:转小写 lower(‘SQL Course‘) --> sql course UPPER:转大写 upper(‘ SQL Course‘) --->SQL COURSE INITCAP:首字母转大写,其余转小写 initcap(‘SQL Course‘) --> Sql Course
右链接 正好相反 --例题:哪些人是领导。 select distinct b.id,b.last_name manager from s_emp a,s_emp b where a.manager_id=b.id(+); 左右顺序有区别,这是另外新建一个表,要显示的是第二个表格的内容。 +放在没有匹配行的表一侧,令表格能完整显示出来。
标准写法:内连接用INNER,左连接用LEFT,右连接用RIGHT。 select distinct b.id,b.last_name manager from s_emp a LEFT join s_emp b ON a.manager_id=b.id;
JOIN: 连结数据库 以一个 select 命令取得及运用多个数据表里的数据。 语法: SELECT select_list FROM table_1, table_2 [, table_3]... WHERE [table_1 . ]column join_operator [table_2 . ] column 如:找出身兼编辑和作者的人 SELECT ed_name FROM editors, authors WHERE ed_id = au_id ; 符号: *= 把第一个数据表里的所有数据列都含括到查讯结果内 =* 把第二个数据表里的所有数据列都含括到查询结果内
十、组函数: 分组允许将数据分为多个逻辑组,以便能对每个组进行聚集计算。 Group: 分组 Group by:分组。(默认按升序对所分的组排序;想要降序要用 order by)可以包括任意数目的列。 如果嵌入了分组,数据将在最后规定的分组上进行汇总。 GROUP BY 子句中列出的每个列都必须是检索列或有效的表达式,但不能是聚集函数。 *如果在 SELECT 中使用表达式,则必须在 GROUP BY 子句中指定相同的表达式,不能使用别名。 除聚合计算语句外, SELECT 语句中的每个列都必须在 GROUP BY 子句中给出。 如果分组列中具有 NULL 值,则 NULL 将作为一个分组返回。如果列中有多行 NULL , 它们将分为一组。
Having: 过滤。分组之后,不能再用 where , 要用 having 选择过滤。 Having 不能单独存在,必须跟在 group by 后面。 WHERE 在数据分组前进行过滤, HAVING 在数据分组后过滤。 可以在SQL中同时使用 WHERE 和 HAVING , 先执行 WHERE , 再执行 HAVING 。
子查询:查询语句的嵌套 可以用于任意select 语句里面,但子查询不能出现 order by。 子查询总是从内向外处理。作为子查询的SELECT 语句只能查询单个列,企图检索多个列,将会错误。 如:找出工资最低的人select min(last_name),min(salary) from s_emp; 或者用子查询select last_name,salary from s_emp where salary=(select min(salary) from s_emp);
约束:针对表中的字段进行定义的。 PK: primary key (主键约束,PK=UK+NN)保证实体的完整性,保证记录的唯一 主键约束,唯一且非空,并且每一个表中只能有一个主键,有两个字段联合作为主键, 只有两个字段放在一起唯一标识记录,叫做联合主键(Composite Primary Key)。 FK: foreign key (外建约束)保证引用的完整性,外键约束,外键的取值是受另外一张表中的主键或唯一值的约束,不能够取其它值, 只能够引用主键会唯一键的值,被引用的表,叫做parent table(父表),引用方的表叫做child table(子表); child table(子表),要想创建子表,就要先创建父表,后创建子表,记录的插入也是如此,先父表后子表, 删除记录,要先删除子表记录,后删除父表记录, 要修改记录,如果要修改父表的记录要保证没有被子表引用。要删表时,要先删子表,后删除父表。 U: UNIQUE key(唯一键 UK),值为唯一,不能重复。 在有唯一性约束的列,可以有多个空值,因为空值不相等。 NN: NOT NULL ,不能为空。 DEFAULT : 制定默认值,当使用者没输入时自动补上。 如:create table tb_score(memid int , courseid int, points numeric(10,1) default 0); CHECK: 指定特定字段里能输入的数据。限定数据范围的方法之一。 如:create table tb_test(memid int, sex varchar(5), points numeric(10,1), CHECK ( points>=0 and points<=100 and sex in (‘man‘, ‘women‘) ) ); REFERENCES: 该字段的数据值必须存在于被参考的主键表格里,否则拒绝输入。
数量关系: 一对一关系 多对一关系 一对多关系 多对多关系
创建用户组表: create table t_group ( id int not null, name varchar(30), primary key (id) ); #只为下面举例用。
外键约束方式: 1.级联(cascade)方式 create table t_user ( userid int not null, name varchar(30), groupid int, primary key (userid), /*定义这表的主键 */ foreign key (groupid) references t_group(id) on delete cascade on update cascade /* 上句:定义外键,groupid 是 t_group表的 id 字段的外键。而且这边groupid的值对应那边的id。 当t_group表的 id 字段被删除或修改,这里相应的 groupid 跟着被删除或修改。级联删除、级联修改。 插入时,如果是t_group表的id字段没有的值,无法插入。参照完整性约束不符。 比如 insert into t_user values (3, ‘dai‘, 3); 如果t_group表的id没有一个是3的,则插入不成功。 */ ); -- 建完表后的修改写法(效果同上): ALTER TABLE t_user add FOREIGN KEY(userid) REFERENCES t_group(id) on delete cascade on update cascade; -- 刪除外键(key 后面的名称得看具体情况) ALTER TABLE t_user drop FOREIGN KEY t_user_ibfk_1;
2.置空(set null)方式 create table t_user ( userid int not null primary key, name varchar(30), groupid int, foreign key (groupid) references t_group(id) on delete set null on update set null /* 插入时,同上。如果是t_group表的id字段没有的值,无法插入。参照完整性约束不符。 当t_group表的 id 字段被删除或修改,这里相应的 groupid 被设为 null 。 */ );
3.禁止(no action / restrict)方式 create table t_user ( id int not null primary key, name varchar(30), groupid int, foreign key (groupid) references t_group(id) on delete no action on update no action /* 插入时,还是同上。如果参照完整性约束不符则无法插入。 当t_group表的 id 字段被删除或修改,参照这里相应的 groupid,如果这里有引用,则主表不能删除或修改 */ );
外键的定义语法: [CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...) REFERENCES tbl_name (index_col_name, ...) [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}] [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}] 该语法可以在 CREATE TABLE 和 ALTER TABLE 时使用,如果不指定 CONSTRAINT symbol,MYSQL会自动生成一个名字。 ON DELETE 、 ON UPDATE 表示事件触发限制,可设参数: RESTRICT(限制外表中的外键改动) CASCADE(跟随外键改动) SET NULL(设空值) SET DEFAULT(设默认值) NO ACTION(无动作,默认的,作用同 RESTRICT )
修改MySQL的字符集: 安装目录下找到“my.ini”,设置“default-character-set=utf8”重启MySQL生效 可设成:gbk,gb2312,big5,utf8 通过MySQL命令行修改: mysql> set character_set_client=utf8; mysql> set character_set_connection=utf8; mysql> set character_set_database=utf8; mysql> set character_set_results=utf8; mysql> set character_set_server=utf8; mysql> set character_set_system=utf8; mysql> set collation_connection=utf8; mysql> set collation_database=utf8; mysql> set collation_server=utf8; 查看其字符集:show variables like ‘character%‘;
修改数据库的字符集 mysql>use mydb mysql>alter database mydb character set utf8; 创建数据库指定数据库的字符集 mysql>create database mydb character set utf8; --ft_running_status 查看某表的字符集:show create table 表名; 修改某表的字符集:ALTER TABLE 表名 DEFAULT CHARSET utf8;
SQL Server 创建用户 --建立登录帐号 sp_addlogin userName, password, userdatabase sp_AddUser ‘useName‘ --授权访问 sp_grantdbaccess userName --指定权限 grant {all|Insert|......} to userName grant select, insert, delete on tableName to userNameOrGroupName --指定到某张表
MySql用户创建、授权以及删除 mysql> CREATE USER 用户名 IDENTIFIED BY ‘密码‘; -- 填上想要的用户名密码即可 上面建立的用户可以在任何地方登陆。 如果要限制在固定地址登陆,比如localhost 登陆: mysql> CREATE USER 用户名@localhost IDENTIFIED BY ‘密码‘; -- localhost 可换上任意ip地址,“%”表示任意地址
若需要授权,用 grant: 格式:grant select on 数据库.* to 用户名@登录主机 identified by "密码"; 如:mysql> GRANT ALL PRIVILEGES ON *.* TO user;@localhost 如:mysql> grant select,insert,update,delete on *.* to utest1@"%" Identified by "abc";
修改密码: mysql> grant all privileges on 数据库.* to utest1@localhost identified by ‘mimi‘;
flush: mysql> flush privileges;
查看用户信息: mysql> select host,user from mysql.user;
注:创建用户时,如果提示“table ‘user‘ is read only”,则需要在控制台运行: "安装目录下\bin\mysqladmin" -u<用户名> -p<密码> flush-tables
查看 oracle 表结构: 1.在 SQLPLUS中,直接用 DESC[ribe] tablename 即可。 可要是在外部应用程序调用查看ORACLE中的表结构时,这个命令就不能用了。 只能用下面的语句代替: 2.看字段名与数据类型 select * from user_tab_columns WHERE TABLE_name = upper(‘表名‘); //查看全部列 查看某些列 select column_name,data_type,data_length,DATA_PRECISION,DATA_SCALE from all_tab_columns where table_name=upper(‘表名‘); 3.可以通过 user_constraints 查看所有约束 select * from user_constraints where table_name = upper(‘表名‘); 查看主键约束: select * from user_constraints where constraint_type=‘P‘ and TABLE_name=upper(‘表名‘);
1、查找表的所有索引(包括索引名,类型,构成列): select t.*,i.index_type from user_ind_columns t,user_indexes i where t.index_name = i.index_name and t.table_name = i.table_name and t.table_name = 要查询的表 2、查找表的主键(包括名称,构成列): select cu.* from user_cons_columns cu, user_constraints au where cu.constraint_name = au.constraint_name and au.constraint_type = ‘P‘ and au.table_name = 要查询的表 3、查找表的唯一性约束(包括名称,构成列): select column_name from user_cons_columns cu, user_constraints au where cu.constraint_name = au.constraint_name and au.constraint_type = ‘U‘ and au.table_name = 要查询的表 4、查找表的外键(包括名称,引用表的表名和对应的键名,下面是分成多步查询): select * from user_constraints c where c.constraint_type = ‘R‘ and c.table_name = 要查询的表 查询外键约束的列名: select * from user_cons_columns cl where cl.constraint_name = 外键名称 查询引用表的键的列名: select * from user_cons_columns cl where cl.constraint_name = 外键引用表的键名 5、查询表的所有列及其属性 select t.*,c.COMMENTS from user_tab_columns t,user_col_comments c where t.table_name = c.table_name and t.column_name = c.column_name and t.table_name = 要查询的表
查看 MySQL 表结构: desc 表名; describe 表名; show columns from 表名; show create table 表名; select * from information_schema.columns where table_name=‘表名‘;
查看 SQL SERVER 表结构: SELECT * from user_cons_columns; select COLUMN_NAME from all_cons_columns a, all_constraints b where a.CONSTRAINT_NAME=b.CONSTRAINT_NAME and b.CONSTRAINT_TYPE= ‘P‘ AND b.TABLE_NAME=‘你的表名‘;
MySQL 注释符号: # 单行注释 -- 单行注释 /* ... */ 多行注释
MySQL 的大小写的: MySQL 的查询默认是不区分大小写的 如: select * from table_name where a like ‘a%‘ select * from table_name where a like ‘A%‘ 效果是一样的。
要让mysql查询区分大小写,可以: select * from table_name where binary a like ‘a%‘ select * from table_name where binary a like ‘A%‘ 也可以在建表时,加以标识 create table table_name(a varchar (20) binary);
MySQL 查询时使用变量: 如果查询时需要用变量,而又不希望用存储过程,可以直接使用临时变量(仅本次连结有效) 变量以“@”开头,赋值时用“:=”符号; 事先可以不需声明而直接使用,只是初始值为空 如: (注意:第一次使用时,值为空,故需要用 ifnull 函数) Select openaccount, iodate, amt as inAmt, 0 as outAmt, @a:=ifnull(@a,0)+amt as _sum From ev_cash where type=1 and openaccount={?OpenAccount} And iodate between ‘{?StartDate}‘ and ‘{?EndDate}‘ union Select openaccount, iodate, 0 as inAmt, amt as outAmt, remark, @a:=@a-amt as _sum From ev_cash where type=2 and openaccount={?OpenAccount} And iodate between ‘{?StartDate}‘ and ‘{?EndDate}‘
MySQL 存储过程: 一个存储过程包括名字,参数列表,以及可以包括很多SQL语句的SQL语句集。 在这里对局部变量,异常处理,循环控制和IF条件句有新的语法定义。 在5.0以上版本可用存储过程,检查版本可用语句: SHOW VARIABLES LIKE ‘version‘; 或者 SELECT VERSION(); CREATE PROCEDURE procedure1 /* name 存储过程名 */ (IN parameter1 INTEGER) /* parameters 参数 */ BEGIN /* start of block 语句块头 */ DECLARE variable1 CHAR(10); /* variables变量声明, 一定要在開頭的語句 */ IF parameter1 = 17 or parameter1 > 50 THEN /* start of IF IF条件开始 */ SET variable1 = ‘birds‘; /* assignment 赋值 */ SET variable1 = ‘ddd‘; /* assignment 操作語句2,這裡只為模擬 */ ELSE SET variable1 = ‘beasts‘; /* assignment 赋值 */ END IF; /* end of IF IF结束 */ INSERT INTO table1 VALUES (variable1); /* statement SQL语句 */ END /* end of block 语句块结束 */
mysql 执行字符串的sql语句: mysql> PREPARE stmt1 FROM ‘SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse‘; mysql> SET @a = 3; mysql> SET @b = 4; mysql> EXECUTE stmt1 USING @a, @b;
没参数的: mysql> PREPARE stmt1 FROM ‘SELECT * from articalinfo‘; mysql> EXECUTE stmt1 执行完的sql删除的时候用下面的语句: mysql> DEALLOCATE PREPARE stmt1;
mysql 创建表时: CREATE TABLE tableName ( `item1` date NOT NULL, `item2` varchar(50) default NULL, `item3` int(10) unsigned NOT NULL, PRIMARY KEY (`item2`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; # ENGINE=MyISAM 表示不支持事务,ENGINE=InnoDB 支持事务。 DEFAULT CHARSET=utf8 默认字符集
MYSQL的事务处理 1、用begin,rollback,commit来实现 begin 开始一个事务 rollback 事务回滚 commit 事务确认 2、直接用set来改变mysql的自动提交模式 MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过 set autocommit=0 禁止自动提交 set autocommit=1 开启自动提交 但注意当你用 set autocommit=0 的时候,你以后所有的SQL都将做为事务处理,直到你用commit确认或rollback结束,注意当你结束这个事务的同时也开启了个新的事务!按第一种方法只将当前的作为一个事务! MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其他的类型是不支持的!(切记!)
判断空值及转换: 下面,如果 orders表的 字段price 为null的话,用0.0替换 SQL Server: select isnull(price,0.0) from orders Oracle: select nvl(price,0.0) from orders MySQL: select ifnull(price,0.0) from orders 通用: select if(price is null, 0.0, price) from orders
另外,判断条件的 is not null,is null 都一样 select * from orders where price is not null
实例: 1. 多重查询( 基于MySQL ) select count(*) as allNums, sum(isFillIn) as Fillin, sum(if(98Nums=3 or (98Nums=2 and it102 != 0),1,0)) as 98Num3 from ( select case item298 when 0 then 1 else 0 end isFillIn, case item298 when -2 then 1 else 0 end isSuspend, if(isnull(left(a.item250,1)) or ifnull(item298,-2)<>0,0,left(a.item250,1)) as 98Nums FROM ft_running_status AS a where a.years=98 " ) f
select ‘期初餘額‘ as type, (a.amt + b.amt) as inAmt from ( (select if(sum(amt) is null,0, sum(amt)) as amt from ev_cash where type=1 and iodate < ‘2010/06/26‘) as a, (select if(sum(amt) is null,0, sum(amt)) as amt from ev_atm where tdate < ‘2010/06/26‘) as b )
2. 找领导: (member表,manager_id表示领导id) select id,last_name from member out where exists (select ‘x‘ from member where manager_id = out.id); 或者(效率低点): select id,last_name from member out where id in (select manager_id from member);
3. IF 条件 ( 仅MySQL 测试过,其他未测试 ) -- 如果 表1 里面有 custid=‘TW00‘ 的资料,则只查询此一笔资料;否则查询所有资料 select * from 表1 where if(exists (select ‘V‘ from 表1 where custid=‘TW00‘), custid=‘TW00‘,1=1 )
select distinct memid, (select points from tb_score where classid=‘1001‘ and memid=s.memid ) JAVA, (select points from tb_score where classid=‘1002‘ and memid=s.memid) SQL, (select points from tb_score where classid=‘1003‘ and memid=s.memid) JSP, (select points from tb_score where classid=‘1004‘ and memid=s.memid) C from tb_score s
5. case 用法: select MEM_ID, NAME, AVGPOINT, (case type when ‘student‘ then ‘学生‘ when ‘teacher‘ then ‘老师‘ else ‘其它‘ end ) ‘type‘, (case when (sex=‘m‘) then ‘男‘ else ‘女‘ end ) as ‘sex‘ from tb_member
case + count : count里可用条件语句 select count(*) as ‘总数‘, count(case when item248 <= 79 then 1 end) as ‘79前‘ from table1 where item248 is not null and item298=0;
6. 一次性更新多笔记录: update ft_running_status as f set f.item11 = (select (case e.country when 2 then _utf8‘美國‘ when 3 then _utf8‘加拿大‘ when 4 then _utf8‘其他‘ else _utf8‘本國‘ end) from enterprise as e where e.id=f.item5)
7.多表更新 -- 更新東琳有,中壢也有的貨品,改貨品數量(多表同时update,方便复杂的条件) update ev_inventory a, ev_inventory b set a.nowqty = a.nowqty+b.nowqty where a.wid=‘中壢‘ and a.pid=b.pid and b.wid=‘東琳‘;
8.update的select子查詢裡面使用自身表(MySQL) -- 建立臨時表,因為同一個表沒法在update的select子查詢裡面使用 drop table if EXISTS tem_inventory; CREATE TABLE tem_inventory AS SELECT * FROM ev_inventory where wid=‘東琳‘ or wid=‘中壢‘;
-- 更新東琳有,而中壢沒有的貨品,直接改倉庫ID即可 update ev_inventory a set a.wid=‘中壢‘ where a.wid=‘東琳‘ and a.pid not in( select b.pid from tem_inventory b where b.wid=‘中壢‘ );
-- 刪除臨時表 drop table if EXISTS tem_inventory;
9. MySQL 查询及删除重复记录的方法 1、查找表中多余的重复记录,重复记录是根据单个字段(pId)来判断(查询出所有重复的资料) select * from 表1 where pId in (select pId from 表1 group by pId having count(*) > 1);
2、删除表中多余的重复记录,重复记录是根据单个字段(pId)来判断,只留有rowid最小的记录 delete from 表1 where pId in (select pId from 表1 group by pId having count(*) > 1) and pId not in (select min(pId) from 表1 group by pId having count(*)>1); -- 建立唯一键来限制也可以,只是会改变表结构 ALTER IGNORE TABLE 資料表 ADD UNIQUE INDEX(欄位1,欄位2);
3、查找表中多余的重复记录(多个字段) select * from 表1 a where (a.pId, a.seq) in (select pId, seq from 表1 group by pId,seq having count(*) > 1);
4、删除表中多余的重复记录(多个字段),只留有rowid最小的记录 delete from 表1 a where (a.pId,a.seq) in (select pId,seq from 表1 group by pId,seq having count(*) > 1) and rowid not in (select min(rowid) from 表1 group by pId,seq having count(*)>1);
/* 用临时表来做重复查询和删除操作; 方便提高效率以及解决不能同表子查询删除的情况 */ -- 原本查询重复的SQL select * from music a where (a.moid, a.seqno) in (select moid, seqno from music group by moid, seqno having count(*) > 1); -- 上面SQL太慢,換用临时表來做 drop table if exists tem; create table tem as select min(oid) as oid, moid, seqno from music group by moid, seqno having count(*) > 1; select a.* from music a, tem t where a.moid=t.moid and a.seqno=t.seqno; -- 刪除错误资料 delete from music where (moid, seqno) in (select moid, seqno from tem) and oid not in (select oid from tem); drop table tem;