mysql复习php
二 基础知识:css
1.数据库的链接vue
mysql -u -p -hjava
-u 用户名mysql
-p 密码ios
-h host主机c++
2:库级知识git
2.1 显示数据库: show databases;web
2.2 选择数据库: use dbname;面试
2.3 建立数据库: create database dbname charset utf8;
2.3 删除数据库: drop database dbname;
3: 表级操做:
3.1 显示库下面的表
show tables;
会把视图页查出来
3.11 查看表结构
Desc 表名/视图名
3.2 查看表的结构:
desc tableName;
3.3 查看表的建立过程:
show create table tableName;
3.32 改表名
Rename table t1 to t2
3.33 删除表
Drop table t1
Drop view v1 删除视图
3.4 建立表:
create table tbName (
列名称1 列类型 [列参数] [not null default ],
....列2...
....
列名称N 列类型 [列参数] [not null default ]
)engine myisam/innodb charset utf8/gbk
3.4的例子:
create table user (
id int auto_increment,
name varchar(20) not null default '',
age tinyint unsigned not null default 0,
index id (id)
)engine=innodb charset=utf8;
注:innodb是表引擎,也能够是myisam或其余,但最经常使用的是myisam和innodb,
charset 经常使用的有utf8,gbk;
为何建表时,加not null default '' / default 0
答:不想让表中出现null值.
为何不想要的null的值
答:
很差比较,null是一种类型,比较时,只能用专门的is null 和 is not null来比较.
碰到运算符,一概返回null
效率不高,影响提升索引效果.
一张表,建立完毕,有了N列.
以后还有可能要增长或删除或修改列
Alter table 表名 add 列名称 列类型 列参数; [加的列在表的最后]
例: alter table m1 add birth date not null default '0000-00-00';
Alter table 表名 add 列名称 列类型 列参数 after 某列 [把新列加在某列后]
例: alter table m1 add gender char(1) not null default '' after username;
Alter table 表名 add 列名称 列类型 列参数 first [把新列加在最前面]
例: alter table m1 add pid int not null default 0 first;
删除列:
Alter table 表名 drop 列名
修改列类型:
Alter table 表名 modify 列名 新类型 新参数
例:alter table m1 modify gender char(4) not null default '';
修改列名及列类型
Alter table 表名 change 旧列名 新列名 新类型 新参数
例:alter table m1 change id uid int unsigned;
做业: 让咱们建一个电子商城, 如何来设计商品表.
再把商城表的字段,一个个删掉,再一个个加上.
并穿插改列操做.
??若是列类型改变了,致使数据存不下怎么办?
好比,int 改为smallint列. 若是不匹配,数据将会丢失,或者在mysql的strict_mode下,修改不了.
4.1
主键 primary key
此列不重复,能区分每一行
注意:一张表 只能1 列为auto_increment 且此列必须加索引
在查询中,咱们常常把查询结果 当成临时表来看.
View是什么? View能够看一张虚拟表. 是表经过某种运算获得的一个投影.
既然视图只是表的某种查询的投影,因此主要步骤在于查询表上.
查询的结果命名为视图就能够了.
视图的定义:
视图是由查询结果造成的一张虚拟表.viem是sql的查询结果
视图的建立语法:
Create view 视图名 as select 语句;
视图的删除语法:
Drop view 视图名
为何要视图?
答:
1:能够简化查询
2: 能够进行权限控制
把表的权限封闭,可是开放相应的视图权限,视图里只开放部分数据
3: 大数据分表时能够用到
好比,表的行数超过200万行时,就会变慢,
能够把一张的表的数据拆成4张表来存放.
News表
Newsid, 1,2,3,4
News1,news2,news3,news4表
把一张表的数据分散到4张表里,分散的方法不少,
最经常使用能够用id取模来计算.
Id%4+1 = [1,2,3,4]
好比 $_GET['id'] = 17,
17%4 + 1 = 2, $tableName = 'news'.'2'
Select * from news2 where id = 17;
还能够用视图, 把4张表造成一张视图
Create view news as select from n1 union select from n2 union.........
视图的修改
Alter view 视图名 as select xxxxxx
视图是表的一个影子.
表与视图,数据变化时的相互影响问题.
视图与表的关系
视图是表的查询结果,天然表的数据改变了,影响视图的结果.
视图改变了呢?
0: 视图增删改也会影响表
1: 可是,视图并是老是能增删改的.
视图某种状况下,是能够修改的.
要求: 视图的数据和表的数据 11对应. 就像函数的映射.
表-->推出视图对应的数据
视图-->推出表对应的数据
对于视图insert还应注意,
视图必须包含表中没有默认值的列.
以这个例子而言,平均价来自于多行的的shop_price的计算结果.
若是pj列的值的变子,映射过去,到底修改哪几行shop_price?
视图的algorithm
Algorithm = merge/ temptable/ undefined
Merge: 当引用视图时,引用视图的语句与定义视图的语句合并.
Temptable:当引用视图时,根据视图的建立语句创建一个临时表
Undefined:未定义,自动,让系统帮你选.
Merge,意味着视图只是一个规则,语句规则, 当查询视图时,
把查询视图的语句(好比where那些)与建立时的语句where子句等合并,分析.
造成一条select 语句.
例: 建立视图的语句:
mysql> create view g2 as select goods_id,cat_id,goods_name,shop_price from goods where shop_price>2000
查询视图的语句:
select * from g2 where shop_price < 3000;
最终执行的语句:
select goods_id,cat_id,goods_name,shop_price from goods where shop_price > 2000 and shop_price < 3000
而temptable是根据建立语句瞬间建立一张临时表,
而后查询视图的语句从该临时表查数据.
create algorethm=temptable view g2 as select goods_id,cat_id,goods_name,shop_price from goods where shop_price > 2000
查询视图的语句:
select * from g2 where shop_price < 3000;
最终执行的2句话: 取数据并放在临时表,而后去查临时表.
Select goods_id,cat_id,goods_name,shop_price from goods where shop_price > 2000;
========> temptable
再次查临时表
Select * from temptable where shop_price< 3000
列类型学习
mysql三大列类型
数值型
整型
Tinyint/ smallint/ mediumint/int/ bigint(M) unsigned zerofill
整型系列所占字节与存储范围的关系.
定性: 占字节越多,存储范围越大.
下图: 是具体的数字分析
整型系统的可选参数 : XXint(M) unsigned zerofill
例: age tinyint(4) unsigned ,或者 stunum smallint(6) zerofill;
Unsigned: 表明此列为无符号类型, 会影响到列的存储范围. (范围从0开始)
(不加unsinged, 则该列默认是有符号类型,范围从负数开始)
Zerofill: 表明0填充, 即: 若是该数字不足参数M位, 则自动补0, 补够M位.
1: 若是没有zerofill属性, 单独的参数M,没有任何意义.
2:若是设置某列为zerofill,则该列已经默认为 unsigned,无符号类型.
小数型
Float(M,D),decimal(M,D)
M叫"精度" ---->表明"总位数",而D是"标度",表明小数位.(小数右边的位数)
浮点数占多大的空间呢
答: float 能存10^38 ,10^-38
若是M<=24, 点4个字节,不然占8字节
用来表示数据中的小数,除了float---浮点.
还有一种叫定点decimal,定点是把整数部分, 和小数部分,分开存储的.
比float精确,他的长度是变化的.
空间上的区别:
Float(M,D), M<=24, 4个字节, 24 <M <=53, 8个字节
Decimal () ,变长字节.
区别: decimal比float精度更高, 适合存储货币等要求精确的数字,
:
字符串型
Char(M)
Varchar(M)
Text 文本类型
日期时间类型
Date 日期
Time 时间
Datetime 时间时间类型
Year 年类型
Mysql 字符串类型
Char 定长类型
Char(M) , M 表明宽度, 0<=M<=255之间
例:Char(10) ,则能输入10个字符. 但只写一个也算10个字符的宽度
Varchar 变长类型
Varchar(M), M表明宽度, 0<=M<=65535(以ascii字符为例,utf822000左右)
类型
类型 |
宽度 |
可存字符 |
实存字符(i<=M) |
实占空间 |
利用率 |
Char |
M |
M |
i |
M |
i/M <= 100% |
Varchar |
M |
M |
i |
i字符+(1-2)字节 |
i/(i+1-2) < 100% |
0000000000
00\0\0\0\0\0 (char型,若是不够M个字符,内部用空格补齐,取出时再把右侧空格删掉)
注:这意味着,若是右侧自己有空格,将会丢失.
Varchar(10)
[2]张三
[3]二麻子
[4]司马相如
Char(8)
00000000
'Hello '
'hello '
Char(M)如何占据M个字符宽度?
答: 若是实际存储内容不足M个,则后面加空格补齐.
取出来的时候, 再把后面的空格去掉.(因此,若是内容最后有空格,将会被清除).
速度上: 定长速度快些
注意: char(M),varchar(M)限制的是字符,不是字节.
即 char(2) charset utf8, 能存2个utf8字符. 好比'中国'char与varchar型的选择原则:
1:空间利用效率, 四字成语表, char(4),
我的简介,微博140字, varchar(140)
2:速度
用户名: char
Char 与 varchar相关实验
Text : 文本类型,能够存比较大的文本段,搜索速度稍慢.
所以,若是不是特别大的内容,建议用char,varchar来代替.
Text 不用加默认值 (加了也没用).
Blob,是二进制类型,用来存储图像,音频等二进制信息.
意义: 2进制,0-255都有可能出现.
Blob在于防止由于字符集的问题,致使信息丢失.
好比:一张图片中有0xFF字节, 这个在ascii字符集认为非法,在入库的时候,被过滤了.
日期时间类型
Year 年(1字节) 95/1995, [1901-2155],
在insert时,能够简写年的后2位,可是不推荐这样.
[00-69] +2000
[70-99] + 1900,
即: 填2位,表示 1970 - 2069
Date 日期 1998-12-31
范围: 1000/01/01 ,9999/12/31
Time 时间 13:56:23
范围: -838:59:59 -->838:59:59
datetime 时期时间 1998-12-31 13:56:23
范围: 1000/01//01 00:00:00 ---> 9999:12:31 23:59:59
timestamp
时间戳:
是1970-01-01 00:00:00 到当前的秒数.
通常存注册时间,商品发布时间等,并非用datetime存储,而是用时间戳.
由于datetime虽然直观,但计算不便.
3.5 修改表
3.5.1 修改表之增长列:
alter table tbName
add 列名称1 列类型 [列参数] [not null default ] #(add以后的旧列名以后的语法和建立表时的列声明同样)
3.5.2 修改表之修改列
alter table tbName
change 旧列名 新列名 列类型 [列参数] [not null default ]
(注:旧列名以后的语法和建立表时的列声明同样)
3.5.3 修改表之减小列:
alter table tbName
drop 列名称;
3.5.4 修改表之增长主键
alter table tbName add primary key(主键所在列名);
例:alter table goods add primary key(id)
该例是把主键创建在id列上
3.5.5 修改表之删除主键
alter table tbName drop primary key;
3.5.6 修改表之增长索引
alter table tbName add [unique|fulltext] index 索引名(列名);
3.5.7 修改表之删除索引
alter table tbName drop index 索引名;
3.5.8 清空表的数据
truncate tableName;
4:列类型讲解
列类型:
整型:tinyint (0~255/-128~127) smallint (0~65535/-32768~32767) mediumint int bigint (参考手册11.2)
参数解释:
unsigned 无符号(不能为负) zerofill 0填充 M 填充后的宽度
举例:tinyint unsigned;
tinyint(6) zerofill;
数值型
浮点型:float double
格式:float(M,D) unsigned\zerofill;
字符型
char(m) 定长
varchar(m)变长
text
列 实存字符i 实占空间 利用率
char(M) 0<=i<=M M i/m<=100%
varchar(M) 0<=i<=M i+1,2 i/i+1/2<100%
year YYYY 范围:1901~2155. 可输入值2位和4位(如98,2012)
日期时间类型 date YYYY-MM-DD 如:2010-03-14
time HH:MM:SS 如:19:26:32
datetime YYYY-MM-DD HH:MM:SS 如:2010-03-14 19:26:32
timestamp YYYY-MM-DD HH:MM:SS 特性:不用赋值,该列会为本身赋当前的具体时间
5:增删改查基本操做
5.1 插入数据
insert into 表名(col1,col2,……) values(val1,val2……); -- 插入指定列
insert into 表名 values (,,,,); -- 插入全部列
insert into 表名 values -- 一次插入多行
(val1,val2……),
(val1,val2……),
(val1,val2……);
5.3修改数据
update tablename
set
col1=newval1,
col2=newval2,
...
...
colN=newvalN
where 条件;
5.4,删除数据 delete from tablenaeme where 条件;
5.5, select 查询
select count(*) from 表名, 查询的就是绝对的行数,哪怕某一行全部字段全为NULL,也计算在内.
而select couht(列名) from 表名,
查询的是该列不为null的全部行的行数.
语法:
SELECT selection_list /*要查询的列名称*/
FROM table_list /*要查询的表名称*/
WHERE condition /*行条件*/
GROUP BY grouping_columns /*对结果分组*/
HAVING condition /*分组后的行条件*/
ORDER BY sorting_columns /*对结果分组*/
LIMIT offset_start, row_count /*结果限定*/
(1) 条件查询 where a. 条件表达式的意义,表达式为真,则该行取出
b. 比较运算符 = ,!=,< > <= >=
c. like , not like ('%'匹配任意多个字符,'_'匹配任意单个字符)
‘诺基亚_’ 诺基亚加一个字符
‘诺基亚%’ 诺基亚加任意多个字符
in , not in , between and
d. is null , is not null 表示是否是null, 不能用where ...=null
(2) 分组 group by
通常要配合5个聚合函数使用:max,min,sum,avg,count
Select avg(shop_price) from user group by cat_id 分组 每一个cat_id的平均
..... 同理
(3) 筛选 having
Select goods_id, (market_price-shop_price) as sheng from goods
Where 1
Having sheng >200; 筛选出差价大于200的
不能简单地写成where sheng>200
注意,WHERE是对分组前记录的条件,若是某行记录没有知足WHERE子句的条件,那么这行记录不会参加分组;而HAVING是对分组后数据的约束。
(4) 排序 order by
Select goods_id from ecs_goods order by shop_price desc; 降序排列
Asc 或者不写 ,就是升序
Select goods_id from ecs_goods order by cat_id asc, shop_price desc; 先按cat_id排,里面按照shop_price排
(5) 限制 limit 跳过前面n条取x条
Select goods_name from goods order by shop_price desc limit 0,3偏移0行取三行
注:偏移量为0能够不写,但不推荐
6: 链接查询
6.1, 左链接
.. left join .. on
table A left join table B on tableA.col1 = tableB.col2 ;
例句:
select 列名 from table A left join table B on tableA.col1 = tableB.col2
2. 右连接: right join
3. 内链接: inner join
左右链接都是以在左边的表的数据为准,沿着左表查右表.
内链接是以两张表都有的共同部分数据为准,也就是左右链接的数据之交集.
左右与内不一样的是,内遇到是null的就不取了,而左右仍是要取
左链接的语法:
假设A表在左,不动,B表在A表的右边滑动.
A表与B表经过一个关系来筛选B表的行.
语法:
A left join B on 条件 条件为真,则B表对应的行,取出
A left join B on 条件
这一块,造成的也是一个结果集,能够当作一张表 设为C
既如此,能够对C表做查询,天然where,group ,having ,order by ,limit 照常使用
问:C表的能够查询的列有哪些列?
答: A B的列均可以查
主外键是构成表与表关联的惟一途径!
外键是另外一张表的主键!例如员工表与部门表之间就存在关联关系,其中员工表中的部门编号字段就是外键,是相对部门表的外键。
咱们再来看BBS系统中:用户表(t_user)、分类表(t_section)、帖子表(t_topic)三者之间的关系。
例如在t_section表中sid为1的记录说明有一个分类叫java,版主是t_user表中uid为1的用户,即zs!
例如在t_topic表中tid为2的记录是名字为“Java是咖啡”的帖子,它是java版块的帖子,它的做者是ww。
外键就是用来约束这一列的值必须是另外一张表的主键值!!!
l 建立t_user表,指定uid为主键列:
CREATE TABLE t_user(
uid INT PRIMARY KEY AUTO_INCREMENT,
uname VARCHAR(20) UNIQUE NOT NULL
);
l 建立t_section表,指定sid为主键列,u_id为相对t_user表的uid列的外键:
CREATE TABLE t_section(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(30),
u_id INT,
CONSTRAINT fk_t_user FOREIGN KEY(u_id) REFERENCES t_user(uid)
);
l 修改t_section表,指定u_id为相对t_user表的uid列的外键:
ALTER TABLE t_section
ADD CONSTRAINT fk_t_user
FOREIGN KEY(u_id)
REFERENCES t_user(uid);
l 修改t_section表,删除u_id的外键约束:
ALTER TABLE t_section
DROP FOREIGN KEY fk_t_user;
l 一对一:例如t_person表和t_card表,即人和身份证。这种状况须要找出主从关系,即谁是主表,谁是从表。人能够没有身份证,但身份证必需要有人才行,因此人是主表,而身份证是从表。设计从表能够有两种方案:
Ø 在t_card表中添加外键列(相对t_user表),而且给外键添加惟一约束;
Ø 给t_card表的主键添加外键约束(相对t_user表),即t_card表的主键也是外键。
l 一对多(多对一):最为常见的就是一对多!一对多和多对一,这是从哪一个角度去看得出来的。t_user和t_section的关系,从t_user来看就是一对多,而从t_section的角度来看就是多对一!这种状况都是在多方建立外键!
l 多对多:例如t_stu和t_teacher表,即一个学生能够有多个老师,而一个老师也能够有多个学生。这种状况一般须要建立中间表来处理多对多关系。例如再建立一张表t_stu_tea表,给出两个外键,一个相对t_stu表的外键,另外一个相对t_teacher表的外键。
多表查询有以下几种:
l 合并结果集;
l 链接查询
Ø 内链接
Ø 外链接
² 左外链接
² 右外链接
² 全外链接(MySQL不支持)
Ø 天然链接
l 子查询
1. 做用:合并结果集就是把两个select语句的查询结果合并到一块儿!
2. 合并结果集有两种方式:
l UNION:去除重复记录,例如:SELECT * FROM t1 UNION SELECT * FROM t2;
l UNION ALL:不去除重复记录,例如:SELECT * FROM t1 UNION ALL SELECT * FROM t2。
3. 要求:被合并的两个结果:列数、列类型必须相同。
链接查询就是求出多个表的乘积,例如t1链接t2,那么查询出的结果就是t1*t2。
链接查询会产生笛卡尔积,假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。能够扩展到多个集合的状况。
那么多表查询产生这样的结果并非咱们想要的,那么怎么去除重复的,不想要的记录呢,固然是经过条件过滤。一般要查询的多个表之间都存在关联关系,那么就经过关联关系去除笛卡尔积。
你能想像到emp和dept表链接查询的结果么?emp一共14行记录,dept表一共4行记录,那么链接后查询出的结果是56行记录。
也就你只是想在查询emp表的同时,把每一个员工的所在部门信息显示出来,那么就须要使用主外键来去除无用信息了。
使用主外键关系作为条件来去除无用信息
SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno; |
上面查询结果会把两张表的全部列都查询出来,也许你不须要那么多列,这时就能够指定要查询的列了。
SELECT emp.ename,emp.sal,emp.comm,dept.dname FROM emp,dept WHERE emp.deptno=dept.deptno; |
还能够为表指定别名,而后在引用列时使用别名便可。
SELECT e.ename,e.sal,e.comm,d.dname FROM emp AS e,dept AS d WHERE e.deptno=d.deptno; |
2.1 内链接
上面的链接语句就是内链接,但它不是SQL标准中的查询方式,能够理解为方言!SQL标准的内链接为:
SELECT * FROM emp e INNER JOIN dept d ON e.deptno=d.deptno; |
内链接的特色:查询结果必须知足条件。例如咱们向emp表中插入一条记录:
其中deptno为50,而在dept表中只有十、20、30、40部门,那么上面的查询结果中就不会出现“张三”这条记录,由于它不能知足e.deptno=d.deptno这个条件。
2.2 外链接(左链接、右链接)
外链接的特色:查询出的结果存在不知足条件的可能。
左链接:
SELECT * FROM emp e LEFT OUTER JOIN dept d ON e.deptno=d.deptno; |
左链接是先查询出左表(即以左表为主),而后查询右表,右表中知足条件的显示出来,不知足条件的显示NULL。
这么说你可能不太明白,咱们仍是用上面的例子来讲明。其中emp表中“张三”这条记录中,部门编号为50,而dept表中不存在部门编号为50的记录,因此“张三”这条记录,不能知足e.deptno=d.deptno这条件。但在左链接中,由于emp表是左表,因此左表中的记录都会查询出来,即“张三”这条记录也会查出,但相应的右表部分显示NULL。
2.3 右链接
右链接就是先把右表中全部记录都查询出来,而后左表知足条件的显示,不知足显示NULL。例如在dept表中的40部门并不存在员工,但在右链接中,若是dept表为右表,那么仍是会查出40部门,但相应的员工信息为NULL。
SELECT * FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno; |
链接查询心得:
链接不限与两张表,链接查询也能够是三张、四张,甚至N张表的链接查询。一般链接查询不可能须要整个笛卡尔积,而只是须要其中一部分,那么这时就须要使用条件来去除不须要的记录。这个条件大多数状况下都是使用主外键关系去除。
两张表的链接查询必定有一个主外键关系,三张表的链接查询就必定有两个主外键关系,因此在你们不是很熟悉链接查询时,首先要学会去除无用笛卡尔积,那么就是用主外键关系做为条件来处理。若是两张表的查询,那么至少有一个主外键条件,三张表链接至少有两个主外键条件。
你们也都知道,链接查询会产生无用笛卡尔积,咱们一般使用主外键关系等式来去除它。而天然链接无需你去给出主外键等式,它会自动找到这一等式:
l 两张链接的表中名称和类型完成一致的列做为条件,例如emp和dept表都存在deptno列,而且类型一致,因此会被天然链接找到!
固然天然链接还有其余的查找条件的方式,但其余方式均可能存在问题!
SELECT * FROM emp NATURAL JOIN dept; SELECT * FROM emp NATURAL LEFT JOIN dept; SELECT * FROM emp NATURAL RIGHT JOIN dept; |
子查询就是嵌套查询,即SELECT中包含SELECT,若是一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。
l 子查询出现的位置:
Ø where后,做为条件的一部分;
Ø from后,做为被查询的一条表;
l 当子查询出如今where后做为条件时,还可使用以下关键字:
Ø any
Ø all
l 子查询结果集的形式:
Ø 单行单列(用于条件)
Ø 单行多列(用于条件)
Ø 多行单列(用于条件)
Ø 多行多列(用于表)
练习:
1. 工资高于甘宁的员工。
分析:
查询条件:工资>甘宁工资,其中甘宁工资须要一条子查询。
第一步:查询甘宁的工资
SELECT sal FROM emp WHERE ename='甘宁' |
第二步:查询高于甘宁工资的员工
SELECT * FROM emp WHERE sal > (${第一步}) |
结果:
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename='甘宁') |
l 子查询做为条件
l 子查询形式为单行单列
2. 工资高于30部门全部人的员工信息
分析:
查询条件:工资高于30部门全部人工资,其中30部门全部人工资是子查询。高于全部须要使用all关键字。
第一步:查询30部门全部人工资
SELECT sal FROM emp WHERE deptno=30; |
第二步:查询高于30部门全部人工资的员工信息
SELECT * FROM emp WHERE sal > ALL (${第一步}) |
结果:
SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30) |
l 子查询做为条件
l 子查询形式为多行单列(当子查询结果集形式为多行单列时可使用ALL或ANY关键字)
3. 查询工做和工资与殷天正彻底相同的员工信息
分析:
查询条件:工做和工资与殷天正彻底相同,这是子查询
第一步:查询出殷天正的工做和工资
SELECT job,sal FROM emp WHERE ename='殷天正' |
第二步:查询出与殷天正工做和工资相同的人
SELECT * FROM emp WHERE (job,sal) IN (${第一步}) |
结果:
SELECT * FROM emp WHERE (job,sal) IN (SELECT job,sal FROM emp WHERE ename='殷天正') |
l 子查询做为条件
l 子查询形式为单行多列
4. 查询员工编号为1006的员工名称、员工工资、部门名称、部门地址
分析:
查询列:员工名称、员工工资、部门名称、部门地址
查询表:emp和dept,分析得出,不须要外链接(外链接的特性:某一行(或某些行)记录上会出现一半有值,一半为NULL值)
条件:员工编号为1006
第一步:去除多表,只查一张表,这里去除部门表,只查员工表
SELECT ename, sal FROM emp e WHERE empno=1006 |
第二步:让第一步与dept作内链接查询,添加主外键条件去除无用笛卡尔积
SELECT e.ename, e.sal, d.dname, d.loc FROM emp e, dept d WHERE e.deptno=d.deptno AND empno=1006 |
第二步中的dept表表示全部行全部列的一张完整的表,这里能够把dept替换成全部行,但只有dname和loc列的表,这须要子查询。
第三步:查询dept表中dname和loc两列,由于deptno会被做为条件,用来去除无用笛卡尔积,因此须要查询它。
SELECT dname,loc,deptno FROM dept; |
第四步:替换第二步中的dept
SELECT e.ename, e.sal, d.dname, d.loc FROM emp e, (SELECT dname,loc,deptno FROM dept) d WHERE e.deptno=d.deptno AND e.empno=1006 |
l 子查询做为表
l 子查询形式为多行多列
同窗见面会:
男生表
姓名 |
配偶 |
张三 |
A |
李四 |
B |
王五 |
C |
高富帅 |
D |
郑七 |
E |
女生表
姓名 |
配偶 |
空姐 |
B |
大S |
C |
阿娇 |
D |
张柏芝 |
D |
林黛玉 |
E |
宝钗 |
F |
主持人大声说:
全部的男士,站到舞台上,带上本身的配偶,(没有的拿块牌子, 上写NULL)
思考:张三上不上舞台呢?
答:上,
问:张三没有对应的行怎么办?
答:用NULL补齐
结果以下
姓名 |
配偶 |
女生姓名 |
配偶 |
张三 |
A |
NULL |
NULL |
李四 |
B |
空姐 |
B |
王五 |
C |
大S |
C |
高富帅 |
D |
阿娇 |
D |
高富帅 |
D |
张柏芝 |
D |
郑七 |
E |
林黛玉 |
E |
这种状况就是 男生 left join 女生.
主持人说:全部女生请上舞台,有配偶的带着, 没有的,写个NULL补齐.
Select 女生 left join 男生 on 条件
左右链接是能够互换的
A left join B, 就等价于 B right join A
注意:既然左右链接能够互换,尽可能用左链接,出于移植时兼容性方面的考虑.
内链接的特色
主持人说: 全部有配偶的男生/女生,走到舞台上来
这种状况下: 张三和宝钗都出局
姓名 |
配偶 |
女生姓名 |
配偶 |
李四 |
B |
空姐 |
B |
王五 |
C |
大S |
C |
高富帅 |
D |
阿娇 |
D |
高富帅 |
D |
张柏芝 |
D |
郑七 |
E |
林黛玉 |
E |
若是从集合的角度
A inner join B
和 left join /right join的关系
答: 内链接是左右链接的交集
问题:
主持人说:全部男生/女生,走上舞台.
有配偶的,带着配偶;
没配偶的,拿牌子写NULL
即:结果是左右链接的并集
这种叫作外链接,可是,在mysql中不支持外链接
Union:合并2条或多条语句的结果
语法:
Sql1 union sql2
可否从2张表查询再union呢?
答:能够,union 合并的是"结果集",不区分在自于哪一张表.
问:取自于2张表,经过"别名"让2个结果集的列一致.
那么,若是取出的结果集,列名字不同,还可否union.
答:能够,以下图,并且取出的最终列名,以第1条sql为准
问:union知足什么条件就能够用了?
答:只要结果集中的列数一致就能够.
问:列的类型不同,也行吗?
答:能够,列名称未必要一致 会使用第一条sql的列名称
问: union后结果集,能否再排序呢?
答:能够的.
Sql1 union sql2 order by 字段
注意: order by 是针对合并后的结果集排的序.
若是不是union all 就会把彻底相同的行合并在一块儿
问: 使用order by 的注意事项
以下,内层语句的desc怎么没发挥做用呢?
思考以下语句:
(SELECT goods_id,cat_id,goods_name,shop_price FROM goods WHERE cat_id = 4 ORDER BY shop_price DESC)
UNION
(SELECT goods_id,cat_id,goods_name,shop_price FROM goods WHERE cat_id = 5 ORDER BY shop_price DESC)
order by shop_price asc;
Union的子句中,不用写orderBy
Sql合并后获得的总的结果,能够orderby ,子句orderby就失去意义了
所以:内层的order by 语句单独使用,不会影响结果集,仅排序,
在执行期间,就被Mysql的代码分析器给优化掉了.
内层的order by 必须可以影响结果集时,才有意义.
好比 配合limit 使用. 以下例.
思考下个问题:
查出: 第3个栏目下,价格前3高的商品,和第4个栏目下,价格前2高的商品.
用union来完成
这一次:内层的order by 发挥了做用,由于有limit ,order 会实际影响结果集,有意义.
若是Union后的结果有重复(即某2行,或N行,全部的列,值都同样),怎么办?
答:这种状况是比较常见的,默认会去重.
问:若是不想去重怎么办?
答: union all
7 子查询
where 型子查询:内层sql的返回值在where后做为条件表达式的一部分
若是 where 列=(内层sql),则内层sql返回的必是单行单列,单个值
若是 where 列 in (内层sql), 则内层sql只返回单列,能够多行.
例句: select * from tableA where colA = (select colB from tableB where ...);
每一个栏目下最想的商品
from 型子查询:内层sql查询结果,做为一张表,供外层的sql语句再次查询
例句:select * from (select * from ...) as tableName where ....
9. 存储引擎
Show table status where name=’t11’
就能够查看表的信息 能够看到引擎
存储引擎 engine=1\2
1 Myisam 速度快 不支持事务 回滚
2 Innodb 速度慢 支持事务,回滚
字符集与乱码问题
客服端sql编码 character_set_client
服务器转化后的sql编码 character_set_connection
服务器返回给客户端的结果集编码 character_set_results
快速把以上3个变量设为相同值: set names 字符集
➕页面自己 ... 这几步设完就不乱码了
校对集
就是按照什么排序而已
经常使用函数
Floor(向下取整)
Round 四舍五入
Rand() 0到1的随机值
Ceiling 向上取整
Count 非null的个数
Cancat(s1,s2) ...连起来
Length 返回字符串str中的字符数
Trim 去掉头尾空格
索引
是数据的目录,能快速定位行数据的位置
提升查询速度,可是下降了增删改的速度,因此使用索引时,要综合考虑.
通常在查询频率高的列上加,并且在重复列上加效果更好
索引不是越多越好,通常咱们在常出现于条件表达式中的列加索引.
值越分散的列,索引的效果越好
索引类型
primary key主键索引
Key 普通索引
unique key'惟一性索引
Email已经重复了,就不让你加
索引长度:建索引时,只取前n个字符当作索引
多列索引 :就是把2列或多列的值的当成一个索引
冗余索引 : 就是在某个列上,可能存在多个索引
好比xm(xing,ming) ming(ming)
索引操做:
查看:show index from t1 或者creat table t1
删除:alter table t1 或者drop index m;
修改 alter table t1 add index/unique 索引名(列名)
事务:
必须选择innodb---支持事务
①开启事务 start transaction
②运行sql;
③提交,同时生效\回滚 commit\rollback
综合练习:
链接上数据库服务器
建立一个gbk编码的数据库
创建商品表和栏目表,字段以下:
商品表:goods
goods_id --主键,
goods_name -- 商品名称
cat_id -- 栏目id
brand_id -- 品牌id
goods_sn -- 货号
goods_number -- 库存量
shop_price -- 价格
goods_desc --商品详细描述
栏目表:category
cat_id --主键
cat_name -- 栏目名称
parent_id -- 栏目的父id
建表完成后,做如下操做:
删除goods表的goods_desc 字段,及货号字段
并增长字段:click_count -- 点击量
在goods_name列上加惟一性索引
在shop_price列上加普通索引
在clcik_count列上加普通索引
删除click_count列上的索引
对goods表插入如下数据:
+----------+------------------------------+--------+----------+-----------+--------------+------------+-------------+
| goods_id | goods_name | cat_id | brand_id | goods_sn | goods_number | shop_price | click_count |
+----------+------------------------------+--------+----------+-----------+--------------+------------+-------------+
| 1 | KD876 | 4 | 8 | ECS000000 | 10 | 1388.00 | 7 |
| 4 | 诺基亚N85原装充电器 | 8 | 1 | ECS000004 | 17 | 58.00 | 0 |
| 3 | 诺基亚原装5800耳机 | 8 | 1 | ECS000002 | 24 | 68.00 | 3 |
| 5 | 索爱原装M2卡读卡器 | 11 | 7 | ECS000005 | 8 | 20.00 | 3 |
| 6 | 胜创KINGMAX内存卡 | 11 | 0 | ECS000006 | 15 | 42.00 | 0 |
| 7 | 诺基亚N85原装立体声耳机HS-82 | 8 | 1 | ECS000007 | 20 | 100.00 | 0 |
| 8 | 飞利浦9@9v | 3 | 4 | ECS000008 | 17 | 399.00 | 9 |
| 9 | 诺基亚E66 | 3 | 1 | ECS000009 | 13 | 2298.00 | 20 |
| 10 | 索爱C702c | 3 | 7 | ECS000010 | 7 | 1328.00 | 11 |
| 11 | 索爱C702c | 3 | 7 | ECS000011 | 1 | 1300.00 | 0 |
| 12 | 摩托罗拉A810 | 3 | 2 | ECS000012 | 8 | 983.00 | 14 |
| 13 | 诺基亚5320 XpressMusic | 3 | 1 | ECS000013 | 8 | 1311.00 | 13 |
| 14 | 诺基亚5800XM | 4 | 1 | ECS000014 | 4 | 2625.00 | 6 |
| 15 | 摩托罗拉A810 | 3 | 2 | ECS000015 | 3 | 788.00 | 8 |
| 16 | 恒基伟业G101 | 2 | 11 | ECS000016 | 0 | 823.33 | 3 |
| 17 | 夏新N7 | 3 | 5 | ECS000017 | 1 | 2300.00 | 2 |
| 18 | 夏新T5 | 4 | 5 | ECS000018 | 1 | 2878.00 | 0 |
| 19 | 三星SGH-F258 | 3 | 6 | ECS000019 | 0 | 858.00 | 7 |
| 20 | 三星BC01 | 3 | 6 | ECS000020 | 13 | 280.00 | 14 |
| 21 | 金立 A30 | 3 | 10 | ECS000021 | 40 | 2000.00 | 4 |
| 22 | 多普达Touch HD | 3 | 3 | ECS000022 | 0 | 5999.00 | 15 |
| 23 | 诺基亚N96 | 5 | 1 | ECS000023 | 8 | 3700.00 | 17 |
| 24 | P806 | 3 | 9 | ECS000024 | 148 | 2000.00 | 36 |
| 25 | 小灵通/固话50元充值卡 | 13 | 0 | ECS000025 | 2 | 48.00 | 0 |
| 26 | 小灵通/固话20元充值卡 | 13 | 0 | ECS000026 | 2 | 19.00 | 0 |
| 27 | 联通100元充值卡 | 15 | 0 | ECS000027 | 2 | 95.00 | 0 |
| 28 | 联通50元充值卡 | 15 | 0 | ECS000028 | 0 | 45.00 | 0 |
| 29 | 移动100元充值卡 | 14 | 0 | ECS000029 | 0 | 90.00 | 0 |
| 30 | 移动20元充值卡 | 14 | 0 | ECS000030 | 9 | 18.00 | 1 |
| 31 | 摩托罗拉E8 | 3 | 2 | ECS000031 | 1 | 1337.00 | 5 |
| 32 | 诺基亚N85 | 3 | 1 | ECS000032 | 1 | 3010.00 | 9 |
+----------+------------------------------+--------+----------+-----------+--------------+------------+-------------+
三 查询知识
注:如下查询基于ecshop网站的商品表(ecs_goods)
在练习时能够只取部分列,方便查看.
1: 基础查询 where的练习:
查出知足如下条件的商品
1.1:主键为32的商品
select goods_id,goods_name,shop_price
from ecs_goods
where goods_id=32;
1.2:不属第3栏目的全部商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where cat_id!=3;
1.3:本店价格高于3000元的商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where shop_price >3000;
1.4:本店价格低于或等于100元的商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods where shop_price <=100;
1.5:取出第4栏目或第11栏目的商品(不准用or)
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where cat_id in (4,11);
1.6:取出100<=价格<=500的商品(不准用and)
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where shop_price between 100 and 500;
1.7:取出不属于第3栏目且不属于第11栏目的商品(and,或not in分别实现)
select goods_id,cat_id,goods_name,shop_price from ecs_goods where cat_id!=3 and cat_id!=11;
select goods_id,cat_id,goods_name,shop_price from ecs_goods where cat_id not in (3,11);
1.8:取出价格大于100且小于300,或者大于4000且小于5000的商品()
select goods_id,cat_id,goods_name,shop_price from ecs_goods where shop_price>100 and shop_price <300 or shop_price >4000 and shop_price <5000;
1.9:取出第3个栏目下面价格<1000或>3000,而且点击量>5的系列商品
select goods_id,cat_id,goods_name,shop_price,click_count from ecs_goods where
cat_id=3 and (shop_price <1000 or shop_price>3000) and click_count>5;
1.10:取出第1个栏目下面的商品(注意:1栏目下面没商品,但其子栏目下有)
select goods_id,cat_id,goods_name,shop_price,click_count from ecs_goods
where cat_id in (2,3,4,5);
1.11:取出名字以"诺基亚"开头的商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods where goods_name like '诺基亚%';
1.12:取出名字为"诺基亚Nxx"的手机
select goods_id,cat_id,goods_name,shop_price from ecs_goods
where goods_name like '诺基亚N__';
1.13:取出名字不以"诺基亚"开头的商品
select goods_id,cat_id,goods_name,shop_price from ecs_goos
where goods_name not like '诺基亚%';
1.14:取出第3个栏目下面价格在1000到3000之间,而且点击量>5 "诺基亚"开头的系列商品
select goods_id,cat_id,goods_name,shop_price from ecs_goods where
cat_id=3 and shop_price>1000 and shop_price <3000 and click_count>5 and goods_name like '诺基亚%';
select goods_id,cat_id,goods_name,shop_price from ecs_goods where
shop_price between 1000 and 3000 and cat_id=3 and click_count>5 and goods_name like '诺基亚%';
1.15 一道面试题
有以下表和数组
把num值处于[20,29]之间,改成20
num值处于[30,39]之间的,改成30
mian表
+------+
| num |
+------+
| 3 |
| 12 |
| 15 |
| 25 |
| 23 |
| 29 |
| 34 |
| 37 |
| 32 |
| 45 |
| 48 |
| 52 |
+------+
1.16 练习题:
把good表中商品名为'诺基亚xxxx'的商品,改成'HTCxxxx',
提示:大胆的把列当作变量,参与运算,甚至调用函数来处理 .
substring(),concat()
2 分组查询group:
2.1:查出最贵的商品的价格
select max(shop_price) from ecs_goods;
2.2:查出最大(最新)的商品编号
select max(goods_id) from ecs_goods;
2.3:查出最便宜的商品的价格
select min(shop_price) from ecs_goods;
2.4:查出最旧(最小)的商品编号
select min(goods_id) from ecs_goods;
2.5:查询该店全部商品的库存总量
select sum(goods_number) from ecs_goods;
2.6:查询全部商品的平均价
select avg(shop_price) from ecs_goods;
2.7:查询该店一共有多少种商品
select count(*) from ecs_goods;
2.8:查询每一个栏目下面
最贵商品价格
最低商品价格
商品平均价格
商品库存量
商品种类
提示:(5个聚合函数,sum,avg,max,min,count与group综合运用)
select cat_id,max(shop_price) from ecs_goods group by cat_id;
3 having与group综合运用查询:
3.1:查询该店的商品比市场价所节省的价格
select goods_id,goods_name,market_price-shop_price as j
from ecs_goods ;
3.2:查询每一个商品所积压的货款(提示:库存*单价)
select goods_id,goods_name,goods_number*shop_price from ecs_goods
3.3:查询该店积压的总货款
select sum(goods_number*shop_price) from ecs_goods;
3.4:查询该店每一个栏目下面积压的货款.
select cat_id,sum(goods_number*shop_price) as k from ecs_goods group by cat_id;
3.5:查询比市场价省钱200元以上的商品及该商品所省的钱(where和having分别实现)
select goods_id,goods_name,market_price-shop_price as k from ecs_goods
where market_price-shop_price >200;
select goods_id,goods_name,market_price-shop_price as k from ecs_goods
having k >200;
3.6:查询积压货款超过2W元的栏目,以及该栏目积压的货款
select cat_id,sum(goods_number*shop_price) as k from ecs_goods group by cat_id
having k>20000
3.7:where-having-group综合练习题
有以下表及数据
+------+---------+-------+
| name | subject | score |
+------+---------+-------+
| 张三 | 数学 | 90 |
| 张三 | 语文 | 50 |
| 张三 | 地理 | 40 |
| 李四 | 语文 | 55 |
| 李四 | 政治 | 45 |
| 王五 | 政治 | 30 |
+------+---------+-------+
要求:查询出2门及2门以上不及格者的平均成绩
## 一种错误作法
mysql> select name,count(score<60) as k,avg(score) from stu group by name having k>=2;
+------+---+------------+
| name | k | avg(score) |
+------+---+------------+
| 张三 | 3 | 60.0000 |
| 李四 | 2 | 50.0000 |
+------+---+------------+
2 rows in set (0.00 sec)
mysql> select name,count(score<60) as k,avg(score) from stu group by name;
+------+---+------------+
| name | k | avg(score) |
+------+---+------------+
| 张三 | 3 | 60.0000 |
| 李四 | 2 | 50.0000 |
| 王五 | 1 | 30.0000 |
+------+---+------------+
3 rows in set (0.00 sec)
mysql> select name,count(score<60) as k,avg(score) from stu group by name having k>=2;
+------+---+------------+
| name | k | avg(score) |
+------+---+------------+
| 张三 | 3 | 60.0000 |
| 李四 | 2 | 50.0000 |
+------+---+------------+
2 rows in set (0.00 sec)
#加上赵六后错误暴露
mysql> insert into stu
-> values
-> ('赵六','A',100),
-> ('赵六','B',99),
-> ('赵六','C',98);
Query OK, 3 rows affected (0.05 sec)
Records: 3 Duplicates: 0 Warnings: 0
#错误显现
mysql> select name,count(score<60) as k,avg(score) from stu group by name having k>=2;
+------+---+------------+
| name | k | avg(score) |
+------+---+------------+
| 张三 | 3 | 60.0000 |
| 李四 | 2 | 50.0000 |
| 赵六 | 3 | 99.0000 |
+------+---+------------+
3 rows in set (0.00 sec)
#正确思路,先查看每一个人的平均成绩
mysql> select name,avg(score) from stu group by name;
+------+------------+
| name | avg(score) |
+------+------------+
| 张三 | 60.0000 |
| 李四 | 50.0000 |
| 王五 | 30.0000 |
| 赵六 | 99.0000 |
+------+------------+
4 rows in set (0.00 sec)
mysql> # 看每一个人挂科状况
mysql> select name,score < 60 from stu;
+------+------------+
| name | score < 60 |
+------+------------+
| 张三 | 0 |
| 张三 | 1 |
| 张三 | 1 |
| 李四 | 1 |
| 李四 | 1 |
| 王五 | 1 |
| 赵六 | 0 |
| 赵六 | 0 |
| 赵六 | 0 |
+------+------------+
9 rows in set (0.00 sec)
mysql> #计算每一个人的挂科科目
mysql> select name,sum(score < 60) from stu group by name;
+------+-----------------+
| name | sum(score < 60) |
+------+-----------------+
| 张三 | 2 |
| 李四 | 2 |
| 王五 | 1 |
| 赵六 | 0 |
+------+-----------------+
4 rows in set (0.00 sec)
#同时计算每人的平均分
mysql> select name,sum(score < 60),avg(score) as pj from stu group by name;
+------+-----------------+---------+
| name | sum(score < 60) | pj |
+------+-----------------+---------+
| 张三 | 2 | 60.0000 |
| 李四 | 2 | 50.0000 |
| 王五 | 1 | 30.0000 |
| 赵六 | 0 | 99.0000 |
+------+-----------------+---------+
4 rows in set (0.00 sec)
#利用having筛选挂科2门以上的.
mysql> select name,sum(score < 60) as gk ,avg(score) as pj from stu group by name having gk >=2;
+------+------+---------+
| name | gk | pj |
+------+------+---------+
| 张三 | 2 | 60.0000 |
| 李四 | 2 | 50.0000 |
+------+------+---------+
2 rows in set (0.00 sec)
4: order by 与 limit查询
4.1:按价格由高到低排序
select goods_id,goods_name,shop_price from ecs_goods order by shop_price desc;
4.2:按发布时间由早到晚排序
select goods_id,goods_name,add_time from ecs_goods order by add_time;
4.3:接栏目由低到高排序,栏目内部按价格由高到低排序
select goods_id,cat_id,goods_name,shop_price from ecs_goods
order by cat_id ,shop_price desc;
4.4:取出价格最高的前三名商品
select goods_id,goods_name,shop_price from ecs_goods order by shop_price desc limit 3;
4.5:取出点击量前三名到前5名的商品
select goods_id,goods_name,click_count from ecs_goods order by click_count desc limit 2,3;
5 链接查询
5.1:取出全部商品的商品名,栏目名,价格
select goods_name,cat_name,shop_price from
ecs_goods left join ecs_category
on ecs_goods.cat_id=ecs_category.cat_id;
5.2:取出第4个栏目下的商品的商品名,栏目名,价格
select goods_name,cat_name,shop_price from
ecs_goods left join ecs_category
on ecs_goods.cat_id=ecs_category.cat_id
where ecs_goods.cat_id = 4;
5.3:取出第4个栏目下的商品的商品名,栏目名,与品牌名
select goods_name,cat_name,brand_name from
ecs_goods left join ecs_category
on ecs_goods.cat_id=ecs_category.cat_id
left join ecs_brand
on ecs_goods.brand_id=ecs_brand.brand_id
where ecs_goods.cat_id = 4;
5.4: 用友面试题
根据给出的表结构按要求写出SQL语句。
Match 赛程表
字段名称 字段类型 描述
matchID int 主键
hostTeamID int 主队的ID
guestTeamID int 客队的ID
matchResult varchar(20) 比赛结果,如(2:0)
matchTime date 比赛开始时间
Team 参赛队伍表
字段名称 字段类型 描述
teamID int 主键
teamName varchar(20) 队伍名称
Match的hostTeamID与guestTeamID都与Team中的teamID关联
查出 2006-6-1 到2006-7-1之间举行的全部比赛,而且用如下形式列出:
拜仁 2:0 不来梅 2006-6-21
mysql> select * from m;
+-----+------+------+------+------------+
| mid | hid | gid | mres | matime |
+-----+------+------+------+------------+
| 1 | 1 | 2 | 2:0 | 2006-05-21 |
| 2 | 2 | 3 | 1:2 | 2006-06-21 |
| 3 | 3 | 1 | 2:5 | 2006-06-25 |
| 4 | 2 | 1 | 3:2 | 2006-07-21 |
+-----+------+------+------+------------+
4 rows in set (0.00 sec)
mysql> select * from t;
+------+----------+
| tid | tname |
+------+----------+
| 1 | 国安 |
| 2 | 申花 |
| 3 | 公益联队 |
+------+----------+
3 rows in set (0.00 sec)
mysql> select hid,t1.tname as hname ,mres,gid,t2.tname as gname,matime
-> from
-> m left join t as t1
-> on m.hid = t1.tid
-> left join t as t2
-> on m.gid = t2.tid;
+------+----------+------+------+----------+------------+
| hid | hname | mres | gid | gname | matime |
+------+----------+------+------+----------+------------+
| 1 | 国安 | 2:0 | 2 | 申花 | 2006-05-21 |
| 2 | 申花 | 1:2 | 3 | 公益联队 | 2006-06-21 |
| 3 | 公益联队 | 2:5 | 1 | 国安 | 2006-06-25 |
| 2 | 申花 | 3:2 | 1 | 国安 | 2006-07-21 |
+------+----------+------+------+----------+------------+
4 rows in set (0.00 sec)
6 union查询
6.1:把ecs_comment,ecs_feedback两个表中的数据,各取出4列,并把结果集union成一个结果集.
6.2:3期学员碰到的一道面试题
A表:
+------+------+
| id | num |
+------+------+
| a | 5 |
| b | 10 |
| c | 15 |
| d | 10 |
+------+------+
B表:
+------+------+
| id | num |
+------+------+
| b | 5 |
| c | 15 |
| d | 20 |
| e | 99 |
+------+------+
要求查询出如下效果:
+------+----------+
| id | num |
+------+----------+
| a | 5 |
| b | 15 |
| c | 30 |
| d | 30 |
| e | 99 |
+------+----------+
create table a (
id char(1),
num int
)engine myisam charset utf8;
insert into a values ('a',5),('b',10),('c',15),('d',10);
create table b (
id char(1),
num int
)engine myisam charset utf8;
insert into b values ('b',5),('c',15),('d',20),('e',99);
mysql> # 合并 ,注意all的做用
mysql> select * from ta
-> union all
-> select * from tb;
+------+------+
| id | num |
+------+------+
| a | 5 |
| b | 10 |
| c | 15 |
| d | 10 |
| b | 5 |
| c | 15 |
| d | 20 |
| e | 99 |
+------+------+
参考答案:
mysql> # sum,group求和
mysql> select id,sum(num) from (select * from ta union all select * from tb) as tmp group by id;
+------+----------+
| id | sum(num) |
+------+----------+
| a | 5 |
| b | 15 |
| c | 30 |
| d | 30 |
| e | 99 |
+------+----------+
5 rows in set (0.00 sec)
7: 子查询:
7.1:查询出最新一行商品(以商品编号最大为最新,用子查询实现)
select goods_id,goods_name from
ecs_goods where goods_id =(select max(goods_id) from ecs_goods);
7.2:查询出编号为19的商品的栏目名称(用左链接查询和子查询分别)
7.3:用where型子查询把ecs_goods表中的每一个栏目下面最新的商品取出来
select goods_id,goods_name,cat_id from ecs_goods where goods_id in (select max(goods_id) from ecs_goods group by cat_id);
7.4:用from型子查询把ecs_goods表中的每一个栏目下面最新的商品取出来
select * from (select goods_id,cat_id,goods_name from ecs_goods order by goods_id desc) as t group by cat_id;
7.5 用exists型子查询,查出全部有商品的栏目
select * from category
where exists (select * from goods where goods.cat_id=category.cat_id);
建立触发器:
CREATE trigger tg2
after insert on ord
for each row
update goods set goods_number=goods_number-new.num where id=new.gid
CREATE trigger tg3
after delete on ord
for each row
update goods set goods_number=good_number+old.num where id=old.gid
CREATE trigger tg4
after update on ord
for each row
update goods set goods_number=goods_number+old.num-new.num where id=old.gid