SLQ实战语句总结三.docx

上传人:b****9 文档编号:25025904 上传时间:2023-06-04 格式:DOCX 页数:17 大小:23.06KB
下载 相关 举报
SLQ实战语句总结三.docx_第1页
第1页 / 共17页
SLQ实战语句总结三.docx_第2页
第2页 / 共17页
SLQ实战语句总结三.docx_第3页
第3页 / 共17页
SLQ实战语句总结三.docx_第4页
第4页 / 共17页
SLQ实战语句总结三.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

SLQ实战语句总结三.docx

《SLQ实战语句总结三.docx》由会员分享,可在线阅读,更多相关《SLQ实战语句总结三.docx(17页珍藏版)》请在冰豆网上搜索。

SLQ实战语句总结三.docx

SLQ实战语句总结三

法二【解决上述缺陷】:

1)先找出装在了黑色车上面的发动机的最小马力值;

selectMIN(ENGINE.`power`)fromcarinnerjoinengine

onENGINE.`F_carid`=car.`cid`

wherecar.`color`='black';

2)所有装了发动机的黑色汽车中,马力值等于该最小值的所有记录全出;

select*fromcarinnerjoinengine

oncar.`F_eid`=ENGINE.`eid`

wherecar.`color`='black'andengine.`power`=(selectMIN(ENGINE.`power`)fromcarinnerjoinengine

onENGINE.`F_carid`=car.`cid`wherecar.`color`='black');

###结论:

所以,一对一表中,能增加关联字段的,尽量增加,以便更多使用单表查询;

==【自连接】缺点:

字段太多,造成冗余大。

技术实质:

本表的一条记录的一个字段,和本表的另一条记录的另一个字段,关联。

业务意义:

比如,QQ中的用户,如何表达,用户间互为好友?

∴可以在用户表增加好友关联字段

uidnamegendericq〖friendid〗

1274张三男136********//用户字段越多,好友越多,冗余越大;

1274张三男136********

1274张三男136********

1274张三男1366243115

.................................

1477王伟男137********

此时,想查出每个人关联的好友情况,怎么办?

情况1)问:

想查出1274号用户的所有好友的uid号?

答:

单表;

selectfriendidfromuserwhereuid='1274';

情况2)问:

想查出1274号用户的所有好友的名字?

答:

本表的friendid字段和本表的uid字段关联;---自连接。

//---fromuserasu1innerjoinuserasu2onu1.uid=u2.friendid

答案:

建一个QQdb,一张《users》表,若干相关好友记录。

//见sql文件:

\《▲user.sql》

selectu1.uid,u1.name,u2.uidas`好友id`,u2.nameas`好友名称`

fromuserasu1innerjoinuserasu2

onu1.friendid=u2.uidwhereu1.name='张三'

groupbyu2.uid;---添加groupby,消去好友也有多个好友时的重复记录;---合并为一组。

---当然,实际应用中,因为用户表的其他字段太多,造成冗余大,这样的设计有缺陷,无实用性。

最终可用*-*添加中间好友表解决。

/---外连接

//所有确定了航班的乘客的情况;

select*frompassengerwherescheduled_fisnotnull;

//所有确定了航班的乘客和航班的情况;

select*from`passenger`innerjoinflighton`passenger`.`scheduled_f`=flight.`f_num`;

//所有乘客的航班情况;

select*from`passenger`leftjoinflighton`passenger`.`scheduled_f`=flight.`f_num`;

//“所有航班的售票(乘客)情况”;

select*fromflightleftjoin`passenger`on`passenger`.`scheduled_f`=flight.`f_num`;

==【外连接】

------先交叉连接,然后某一方表的所有行,全部输出,在结果集临时表中显示,另一张表仅关联记录输出。

<左外连接>-----先交叉连接,再左表全显示,右表显示条件匹配值。

//右连接反向。

书写方式)select*from左表LEFTJOIN右表ON连接条件;

《实体关系在Table上的映射》

实体关系:

关联,依赖,继承。

==关联关系映射的种类:

1-1、1-*、*-*;

1-1如何映射到表中:

-映射技术:

1)两表都增加关联字段;---双向关联。

2)两表关联字段对置为主外键,且可以建立约束。

3)简化起见,也可以只建立单边。

---单向关联。

1-*如何映射:

映射技术:

1)多端表加关联字段;---单向关联。

2)一端表主键作多端表关联字段(外键)值,且可以建立约束。

//问题:

为什么不能在一端表添加外键?

因为:

将导致一端表记录,要么外键字段重复组、要么其余字段数据冗余(字段值重复);

求平均值:

法I)null字段也要加入求平均值,null应改为0;

缺点:

动表;优点:

快;

法II)则需要用sum()---算出值总和;用count()---算出记录总数;再作除法;

//练习:

//所有有了乘客的航班的情况

selectflight.*,passenger.`name`as'该乘客是'from`passenger`innerjoinflighton`flight`.`f_num`=passenger.`scheduled_f`;

//所有乘客的航班情况

select`passenger`.`name`,flight.*from`passenger`leftjoin`flight`onpassenger.`scheduled_f`=flight.`f_num`;

//所有已经有航班的乘客的情况

select*frompassengerwherescheduled_fisnotnull;

//“所有没有确定航班的乘客的情况”

select*frompassengerwherescheduled_fisnull;

//“王森乘客的航班详细情况”

select*frompassengerwhereNAME=(selectnamefrompassengerwherescheduled_fisnull);

//“按售票数排名所有航空公司(降序),并列出各公司售票数量”

selectflight.*,COUNT(scheduled_f)fromflightleftjoinpassengeron`flight`.`f_num`=passenger.`scheduled_f`groupbyflight.`company`orderbyscheduled_fdesc;

//级联插入:

8号车记录,12号发动机记录,且8号车装得是12号发动机

insertinto`car`(cid,f_eid,title,color)values(8,12,'BMW','red');

insertinto`engine`(eid,title,product_date,power,f_carid)values(12,'本田','2009-05-26',300,8);

updatecarsetF_eid=eid;

updateenginesetF_carid=cid;

//查出8号车所装发动机号?

selectcidas'车号',f_eidas'发动机号'fromcarwherecid=8;

//查出8号车的品牌?

selectcidas'车号',titleas'车牌'fromcarwherecid=8;

//134号车的发动机的功率?

(前提:

134号车一定装有发动机)

select`engine`.`power`from`engine`where`engine`.eid=(selectf_eidas'发动机号'fromcarwherecid=134);

//若果134车没有装发动机

selectcar.`cid`,`engine`.powerfromcarleftjoin`engine`oncar.`F_eid`=`engine`.`eid`wherecar.`cid`=134;

//列出所有BMW车的发动机功率情况?

selectcar.`title`,engine.powerfromcarleftjoinengineon`car`.`F_eid`=`engine`.`eid`wherecar.`title`='BMW';

//BMW车的发动机平均功率?

selectAVG(`engine`.`power`)as'平均功率'fromcarleftjoinengineoncar.`F_eid`=engine.`eid`wherecar.`title`='BMW';

selectAVG(`engine`.`power`)as'平均功率'fromcarinnerjoinengineoncar.`F_eid`=engine.`eid`wherecar.`title`='BMW';

//---左外连接和内连接记录数不同,但AVG()只对有值字段值求平均值,不包括null;如果null字段也要加入求平均值,null应改为0;

注意:

▲Null值不计算入AVG()平均值;

//AVG()只计算有值记录的平均值;---[有值平均值];

▲如果要求[绝对平均值]---要计算的平均值,是有值的值总和/(有值+没值)记录总数

selectcar.title,AVG(engine.power)fromcarLeftJoinengineoncar.f_eid=engine.eidGROUPBYcar.`title`HAVINGcar.title='BMW';

selectcar.title,AVG(engine.power)fromcarLeftJoinengineoncar.f_eid=engine.eidwherecar.title='BMW'GROUPBYcar.`title`;

//单表过滤用where加在前也可以;

selectcar.`title`,COUNT(*),AVG(`engine`.`power`)as'有值平均功率'

fromcarleftjoinengine

oncar.`F_eid`=engine.`eid`

wherecar.`title`='BMW'

groupbycar.`title`;

//各种牌子汽车的发动机平均功率

selectcar.`title`as'品牌',count(*),AVG(`engine`.`power`)as'平均功率'fromcarleftjoinengineon`car`.`F_eid`=engine.`eid`groupbycar.`title`;

//列出114航班的所有乘客情况?

select`flight`.`id`as'航班号',`passenger`.*frompassengerleftjoinflightonflight.`f_num`=passenger.`scheduled_f`wherepassenger.`scheduled_f`=12956;

//张三所在航班的情况;

分析:

乘客情况---passenger表;

114航班---flight表、passenger表(如果卖了票)

如果没有卖票,则仅在flight表中;

∴---多表;

什么连接---可能没卖票---外连接;

分析:

张三可能坐了飞机,也可能没坐飞机。

selectpassenger.`name`,flight.*frompassengerLEFTJOINflighton`passenger`.`scheduled_f`=`flight`.`f_num`where`passenger`.`name`='张三';

//所有航班的所有乘客的情况。

select*fromflightleftjoinpassengeronflight.`f_num`=passenger.`scheduled_f`;

//某航空公司的所有航班的所有乘客的情况。

select*fromflightleftjoinpassengeron`flight`.`f_num`=passenger.`scheduled_f`whereflight.`company`='中国南方航空';

//分析:

该航空公司,可能航班还没有乘客----外连接。

select*FROMflightasfLEFTJOINpassengeraspONf.`f_num`=p.`scheduled_f`wheref.`company`like'%南方%';

三大范式,---●是老式的数据建模方式,笨拙;

现代按OOP分析实体-关系后,再按OOD映射建立数据模型,之后自然就符合三大范式;无需再单独规范;

《原始表》----缺陷:

记录可能不唯一;可能有重复组;很多查询条件失效;添加、修改都麻烦。

解决方案:

[第一范式](First-NormalForm,1NF)规范化操作;缺陷:

数据冗余大

1)确立主键。

2)消除重复组。

但仍然有冗余。

-结果:

①消除了重复组;②记录唯一了(但可能是复合主键);③但数据冗余大;(复合主键下记录大量字段重复)

解决方案:

[第二范式](Second-NormalForm,2NF)规范化操作;

消除部分依赖性。

//将复合主键拆开,其它主键字段,独立出去,成为一张新表;

结果:

①消除了重复组;②记录唯一了(且是单一主键);③消除部分依赖性,(一表变多表)关联表产生;本表记录唯一,重复记录消失了;

缺陷:

④但传递依赖字段仍可能存在,数据冗余仍有;

仍有一些字段,原来是依赖于分离出去的主键字段而存在于本表中的;其对本表的主键的依赖是通过其它字段传递来的(传递依赖性),其非本表必然字段;

解决方案:

[第三范式](Third-NormalForm,3NF)规范化操作;

消除传递依赖性。

结果:

①消除了重复组;②记录唯一了(且是单一主键);③消除部分依赖性,关联表产生;本表记录唯一,重复记录消失了;④消除传递依赖字段,数据冗余消失;

简记:

总结:

1NF:

1)删除重复组。

一格一值。

2)必有主键。

记录有了唯一性。

---------->【第一范式】1NF

2NF:

3)消除部分依赖性。

拆开复合主键,各主键字段成为独立的表。

---------->【第二范式】2NF

3NF:

4)消除可传递依赖性。

移走不和主键依赖的字段,

-----------------------------------多对多-------------------------------[三表联查]

映射技术:

1)选择或添加一张中间表,该表中建立两个关联字段;分别与原两张表主键建立关联。

2)多端表主键可与中间表关联字段(外键),建立约束。

//一个*-*变成了两个1-*

//--------多对多---------[三表联查]

//sid3号同学的姓名?

selectname,sidfromstudentwheresid='sid3';

//Java这门课的课时

selectname,Timefromcoursewherenamelike'%Java%';

//sid3号同学选了几门课?

select`score`.`f_sid`,COUNT(*)as'所选课程数'fromscorewhere`score`.`f_sid`='sid3'groupbyscore.`f_sid`;//改,标准。

//分析:

如果该同学一门课也没选,学生号只会出现在student表中,所选课程现在score表中----多表;

什么连接?

学号必须出现,右边关联选出,---外连接;

selectstudent.`SID`,COUNT(score.`f_cid`),fromstudentleftjoinscoreonstudent.`SID`=`score`.`f_sid`wherestudent.`SID`='sid3'groupby`student`.`SID`;

//#哪几门课?

//分析:

该同学可能一门课也没选,因此学号应该来自student表;

所选课程在score表中,课程详细情况在course表中;

所以---多表,是3表联查:

student---score---course

什么连接?

没选课的也要出,因此为外连接。

技术点:

3表左外连接查询;

#3表交叉连接

select*fromstudentinnerjoincourseinnerjoinscore;

#3表内连接

select*fromstudentinnerjoincourseinnerjoinscore

onstudent.`SID`=score.`f_sid`

andscore.`f_cid`=course.`cid`

wherestudent.`SID`='sid3';

#3表内连接业务意义:

左表与中表内连接---所有选了课的同学选课情况,

该临时表再与右表内连接---所有选了课的同学的所选课的课程情况(选课情况+课程情况)

//连续2次内连接

#3表外连接

select*fromstudentleftjoinscoreonstudent.`SID`=score.`f_sid`

leftjoincourseonscore.`f_cid`=course.`cid`

wherestudent.`SID`='sid3';

#3表外连接业务意义:

左表与中表外连接---所有同学(选了课的+没选可的)的选课情况;

该临时表再与右表外连接---(临时表全保留)所有同学(选了课的+没选可的)的所选课情况及课程情况

//连续2次外连接

select`student`.sid,course.name,course.timefromstudentleftjoinscoreonstudent.`SID`=score.`f_sid`

leftjoincourseonscore.`f_cid`=course.`cid`

wherestudent.`SID`='sid3';

//sid3号同学选了哪几门课?

考了多少分?

select`student`.`Name`,`score`.`f_cid`,score.`grade`fromstudentleftjoinscoreonstudent.`SID`=`score`.`f_sid`wherescore.`f_sid`='sid3';//原:

片面,没有查到课程的名称(需要三表联查)

//所有选了课的学生的选课情况

selectstudent.`Name`,course.*,score.`grade`fromstudentinnerjoinscoreonstudent.`SID`=score.`f_sid`

innerjoincourseonscore.`f_cid`=course.`cid`;

//"张三选了哪些课?

"

selectstudent.`Name`,score.`f_cid`,course.`name`fromstudentleftjoinscoreonstudent.`SID`=score.`f_sid`

leftjoincourseonscore.`f_cid`=course.`cid`

wherestudent.`Name`='张三';

//"张三选了哪些课,成绩如何?

(张三各科考试情况?

")//"张三选的课,课时是多少?

"

selectstudent.`Name`,score.`f_cid`,course.`name`,course.Time,`score`.`grade`fromstudentleftjoinscoreonstudent.`SID`=score.`f_sid`

leftjoincourseonscore.`f_cid`=course.`cid`

wherestudent.`Name`='张三';

//张三选的课,总课时是多少?

平均课时是多少?

selectstudent.`Name`,score.`f_cid`,course.`name`,sum(course.Time),avg(course.Time)fromstudentleftjoinscoreonstudent.`SID`=score.`f_sid`

leftjoincourseonscore.`f_cid`=course.`cid`

wherestudent.`Name`='张三'

groupbystudent.`Name`;

//◆查出各位同学的Java成绩。

//----最难的题

selectstudent.`Name`,course.nameas'课程名',score.`grade`fromstudentleftjoinscoreonstudent.`SID`=score.`f_sid`leftjoincourseonscore.`f_cid`=course.`cid`wherecourse.name='java';//原,缺陷左表没有选Java的学生都被过滤掉了。

selectstudent.`Name`,course.nameas'课程名',score.`grade`fromstudentleftjoin(scoreinnerjoincourseonscore.`f_cid`

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1