一张叫主表(一方)
一张叫从表(多方):从表(多方)中必须有个字段(列),引用主表(一方)的主键
外键:从表(多方)引用主表(一方)主键的那个字段(列)
中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键.
语法:alter table 从表 add [constraint] 外键名称 foreign key (从表外键字段名) references 主表 (主表的主键);
[外键名称] 用于删除外键约束的,一般建议“_fk”结尾
alter table 从表 drop foreign key 外键名称
1.交叉查询:查询到的数据是两个表相乘(主表(A,B,C),从表(a,b,c))=Aa,Ab,Ac…Ba,Bb,Bc…Ca,Cb,C*c,9条数据
2.内连接查询(使用的关键字 inner join – inner可以省略)
隐式内连接:select * from 主表,从表 where 主表.主键=从表.外键;
显示内连接:select * from A inner join B on 主表.主键=从表.外键;
3.外连接查询:
左外连接:select * from 主表 left outer join 从表 on 主表.主键=从表.外键----以左表为准,左表中的数据必须每条都有;
右外连接:select * from 主表 right outer join 从表 on 主表.主键=从表.外键;
#一对多
CREATE TABLE leimu(
lid INT PRIMARY KEY AUTO_INCREMENT,
lname VARCHAR(100)
);
CREATE TABLE shangpin(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(100),
leimu_id INT,
shangjia INT,
##也可以把外键约束放从表里面,要注意标点符号
CONSTRAINT id_leimu_fk FOREIGN KEY (leimu_id) REFERENCES leimu(lid)
);
ALTER TABLE shangpin ADD CONSTRAINT id_leimu_fk FOREIGN KEY (leimu_id) REFERENCES leimu(lid);
INSERT INTO leimu(lname) VALUES('服装');
INSERT INTO leimu(lname) VALUES('鞋子');
INSERT INTO leimu(lname) VALUES('手机');
INSERT INTO leimu(lname) VALUES('日化');
INSERT INTO leimu(lname) VALUES('汽车');
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('奥迪',5,1);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('宝马',5,1);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('奔驰',5,0);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('沙宣',4,0);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('海飞丝',4,0);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('潘婷',4,1);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('小米',3,0);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('华为',3,1);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('耐克',2,1);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('阿迪',2,0);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('杰克琼斯',1,0);
INSERT INTO shangpin(sname,leimu_id,shangjia) VALUES('优衣库',1,1);
1.
#查看哪些商品上架了
SELECT *FROM shangpin WHERE shangjia=1;
#查看什么类目的商品上架了
#第一步先创建连接
ALTER TABLE shangpin ADD CONSTRAINT shangpin_fk FOREIGN KEY (leimu_id) REFERENCES leimu(lid);
#第二步内连接查询有商品上架的类目(显示全部字段(列))
SELECT * FROM leimu,shangpin WHERE shangpin.leimu_id=leimu.lid AND shangjia>0;
#第三步内连接查询有商品上架的类目(只显示lname字段(列))
SELECT lname FROM leimu,shangpin WHERE shangpin.leimu_id=leimu.lid AND shangjia>0;
#第三步内连接查询有商品上架的类目(去重)
SELECT DISTINCT lname FROM leimu,shangpin WHERE shangpin.leimu_id=leimu.lid AND shangjia>0;
#主表,从表可以简写
SELECT DISTINCT lname FROM leimu l,shangpin sp WHERE sp.leimu_id=l.lid AND shangjia>0;
2.
#查询各个分类的商品个数
内连接查询
SELECT lname,COUNT(*) FROM leimu,shangpin WHERE leimu.lid=shangpin.leimu_id GROUP BY leimu_id;
外连接查询
SELECT lname,COUNT(leimu_id) FROM leimu l LEFT OUTER JOIN shangpin sp ON l.lid = sp.leimu_id GROUP BY lname;
一个查询的结果,作为另外一个查询的一部分
上面例子
#查汽车的详情
SELECT * FROM shangpin WHERE leimu_id=(SELECT lid FROM leimu WHERE lname='汽车');
#查汽车和手机的详情
SELECT * FROM shangpin sp WHERE sp.leimu_id IN( SELECT l.lid FROM leimu l WHERE l.lname IN('汽车','手机'));
CREATE TABLE people(
empno INT PRIMARY KEY AUTO_INCREMENT,#工号
pname VARCHAR(50),
job VARCHAR(50),
mgr INT,#管理者编号
hiredate DATE,#入职时间
sal DECIMAL(7,2),#工资
comm DECIMAL(7,2),#奖金
deptno INT#部门编号
);
INSERT INTO people VALUES(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO people VALUES(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO people VALUES(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO people VALUES(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO people VALUES(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO people VALUES(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO people VALUES(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO people VALUES(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO people VALUES(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO people VALUES(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO people VALUES(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
INSERT INTO people VALUES(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO people VALUES(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
INSERT INTO people VALUES(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);
CREATE TABLE dept(
deptno INT,
dname VARCHAR(14),
loc VARCHAR(13)
);
INSERT INTO dept VALUES(10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO dept VALUES(20, 'RESEARCH', 'DALLAS');
INSERT INTO dept VALUES(30, 'SALES', 'CHICAGO');
INSERT INTO dept VALUES(40, 'OPERATIONS', 'BOSTON');
#单表练习
-- 1. 查询工资大于1200的员工姓名和工资
SELECT pname,sal FROM people WHERE sal>=1200;
-- 2. 查询员工号为7654的员工的姓名和部门号
SELECT pname,deptno FROM people WHERE empno=7654;
-- 3. 选择工资不在1000到2000的员工的姓名和工资
SELECT pname,sal FROM people WHERE sal>2000 OR sal<1000;
-- 4. 选择雇用时间在1981-05-01到1981-10-01之间的员工姓名,job和雇用时间
SELECT pname,job,hiredate FROM people WHERE hiredate >'1981-05-01' AND hiredate <'1981-10-01';
SELECT pname,job,hiredate FROM people WHERE hiredate BETWEEN '1981-05-01' AND '1981-10-01';
-- 5. 选择在20或10号部门工作的员工姓名和部门号
SELECT pname,deptno FROM people WHERE deptno IN (10,20);
-- 6. 选择在1981年雇用的员工的姓名和雇用时间
SELECT pname,hiredate FROM people WHERE hiredate BETWEEN '1981-01-01' AND '1981-12-31'
SELECT pname,hiredate FROM people WHERE hiredate LIKE '1981%';
-- 7. 选择公司中没有管理者的员工姓名及job
SELECT pname,job FROM people WHERE mgr IS NULL;
-- 8. 选择公司中有奖金的员工姓名,工资和奖金
SELECT pname,sal,comm FROM people WHERE comm IS NOT NULL ;
-- 9. 选择员工姓名的第三个字母是a的员工姓名
SELECT pname FROM people WHERE pname LIKE '__a%';
-- 10. 选择姓名中有字母a和e的员工姓名(%代表0个或者多个字符)
SELECT pname FROM people WHERE pname LIKE '%a%e%' OR pname LIKE '%e%a%';
SELECT ename FROM emp WHERE ename LIKE '%a%' AND ename LIKE '%e%';
-- 12. 查询员工号,姓名,工资,以及工资提高百分之20%后的结果(请使用别名new salary)
SELECT empno,pname,sal,sal*1.2 `new salary` FROM people;
-- 13. 将员工的姓名按首字母排序,并写出姓名的长度(length)
SELECT pname,LENGTH(pname) FROM people ORDER BY pname;
-- 14. 查询公司员工工资的最大值,最小值,平均值,总和
SELECT SUM(sal),MAX(sal),MIN(sal),AVG(sal) FROM people;
-- 15. 查询各job的员工工资的最大值,最小值,平均值,总和
SELECT job,SUM(sal),MAX(sal),MIN(sal),AVG(sal) FROM people GROUP BY job ;
-- 16. 查询具体各个job的员工人数
SELECT job,COUNT(pname) FROM people GROUP BY job ;
-- 17. 查询员工最高工资和最低工资的差距(请用别名 DIFFERENCE)
SELECT MAX(sal)-MIN(sal) DIFFERENCE FROM people;
-- 18. 查询各个管理者手下员工的最低工资,其中最低工资不能低于1000,没有管理者的员工不计算在内
SELECT mgr,MIN(sal) FROM people GROUP BY mgr HAVING mgr IS NOT NULL AND MIN(sal)>1000;
-- 19. 查询所有部门的名字,loc,员工数量和工资平均值
SELECT dname,loc,COUNT(people.pname),AVG(people.sal) FROM dept,people WHERE dept.deptno=people.deptno GROUP BY dept.dname;
-- 1、按员工编号升序排列不在10号部门工作的员工信息
SELECT *FROM people WHERE deptno<>10 ORDER BY empno;
-- 2、查询姓名第二个字母不是”A”且薪水大于800元的员工信息,按年薪降序排列
SELECT *,sal*12 nianxin FROM people WHERE NOT pname LIKE "_A%" AND sal>800 ORDER BY nianxin DESC ;
-- 3、求每个部门的平均薪水
SELECT deptno,AVG(sal) FROM people GROUP BY deptno;
-- 4、求各个部门的最高薪水
SELECT deptno,MAX(sal) FROM people GROUP BY deptno;
-- 5、求每个部门每个岗位的最高薪水
SELECT deptno,job, MAX(sal) FROM people GROUP BY deptno,job;
-- 6、求平均薪水大于2000的部门编号
SELECT deptno FROM people GROUP BY deptno HAVING AVG(sal)>2000;
-- 8、求最高薪水的员工信息
SELECT *FROM people WHERE sal=(SELECT MAX(sal) FROM people) ;
-- 9、求多于平均薪水的员工信息
SELECT *FROM people WHERE sal>(SELECT AVG(sal) FROM people);
-- 11、求各个部门薪水最高的员工信息
SELECT *FROM people WHERE sal IN (SELECT MAX(sal) FROM people GROUP BY deptno);
SELECT * FROM people,(SELECT deptno, MAX(sal) maxsal FROM people GROUP BY deptno) d WHERE people.deptno = d.deptno AND people.sal = d.maxsal;
-- 1. 查询和SCOTT相同部门的员工姓名和雇用日期
SELECT pname,hiredate FROM people WHERE deptno=(SELECT deptno FROM people WHERE pname='SCOTT');
-- 2. 查询工资比公司平均工资高的员工的员工号,姓名和工资。
SELECT empno,pname,sal FROM people WHERE sal>(SELECT AVG(sal) FROM people);
-- 3.(难度较高,可删除)查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资
#翻译一下
# 列出员工号,姓名,工资,从people表, (部门平均工资表)自定义名称d 条件是 people表的部门编号=d表的部门编号 且people表的工资>d表的平均工资
SELECT empno,pname,sal FROM people,(SELECT deptno,AVG(sal) avgsal FROM people GROUP BY deptno) d WHERE people.deptno = d.deptno AND people.sal > d.avgsal;
-- 4. 查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名(可以用=也可以用IN)
SELECT empno,pname,deptno FROM people WHERE deptno=(SELECT deptno FROM people WHERE pname LIKE '%u%');
-- 6. 查询管理者是KING的员工姓名和工资
SELECT pname,sal FROM people WHERE mgr IN (SELECT empno FROM people WHERE pname='KING');