仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 846|回复: 8
打印 上一主题 下一主题

[学习教程] MYSQL编程:SQL综合使用进修

[复制链接]
小女巫 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:49:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
“对于MySQL数据库,无论是在开发方面,还是支持方面,现在有大量强大的MySQL学习教程可以选择。每一个新手开发者可以轻松地使用MySQL数据库进行开发。
看完测试完上面这些试题,你的SQL程度必定会有新的进步。


上面我们先看一下题设:
二维表T(F1,F2,F3,F4,F5,F6,F7)暗示以下干系:
┌─────┬────┬─────┬─────┬─────┬─────┬─────┐
│先生ID│先生姓名│课程ID│课程称号│成就│教员ID│教员姓名│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S3│王五│K4│政治│53│T4│赵先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S1│张三│K1│数学│61│T1│张先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S2│李四│K3│英语│88│T3│李先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S1│张三│K4│政治│77│T4│赵先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S2│李四│K4│政治│67│T5│周先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S3│王五│K2│语文│90│T2│王先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S3│王五│K1│数学│55│T1│张先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S1│张三│K2│语文│81│T2│王先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S4│赵六│K2│语文│59│T1│王先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S1│张三│K3│英语│37│T3│李先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│S2│李四│K1│数学│81│T1│张先生│
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│....│││││││
├─────┼────┼─────┼─────┼─────┼─────┼─────┤
│....│││││││
└─────┴────┴─────┴─────┴─────┴─────┴─────┘
为便于人人更好的了解,我们将T表起名为"成就表"

1.假如T表另有一字段F数据范例为主动增量整型(独一,不会反复),
并且T表中含有除F字段外,请删除别的字段完整不异的反复过剩的脏纪录数据:

本成绩就是一个清算"逻辑反复"纪录的成绩,固然,这类情形完整能够使用主键束缚来
根绝!但是,实际情形常常是原始数据在"洗濯"后,方可平安利用,并且逻辑主键过早的
束缚,将会给收罗原始数据带来方便,比方:从刷卡机上读取考勤纪录。到了使用数据
的时分,脏数据就该被扫地出门了!之以是题中要保存一个主动标识列,是由于它切实其实
是上面谜底所必需的条件:

DELETEL
FROM"成就表"L
JOIN"成就表"R
ONL."先生ID"=R."先生ID"ANDL."课程ID"=R."课程ID"ANDL.F>R.F

这是思绪最精致且最间接无效的办法之一。用不等自连接,恰好能够将统一组反复数
据中F字段值最小的那一条留下,并选出别的的删失落,假如只要一条,天然也不会被选
中了。这里还要夸大一下,人人必定要分分明被操纵的基础表也就是DELETE关头字
后的表和过滤前提所利用的由基础表毗连而成的二维表数据集,也就是FROM子句的
全体。在自毗连的FROM子句最少要取一一般名来援用基础表。别号的利用在编写年夜
量相似布局的SQL时十分便利,并且利于一致程序机关静态SQL。若有需要增强前提,
还可持续利用WHERE子句。假如下面的例子还不敷直不雅,上面仿照一个不等自连接,
有一组数(1,2,3),作一个不等自连接,令左子集年夜于右子集,是:
21
31
32
假如如今选出左子集,就是2和3了。1在右侧没有比它更小的数据能够与之婚配,
因而被过滤了。假如数据大批反复,效力会差强者意,亏得不是SELECT,而是DELETE
无需前往了局集,影响天然小多了。

DELETET
FROM成就表T
WHEREFNOTIN(SELECTMIN(F)
FROM成就表I
GROUPBYI.先生ID,I.课程ID
HAVINGCOUNT(*)>1
)
ANDFNOTIN(SELECTMIN(F)
FROM成就表I
GROUPBYI.先生ID,I.课程ID
HAVINGCOUNT(*)=1
)

这类办法思绪很复杂,就像翻译天然言语,很准确地形貌了切合前提纪录的特征,乃至
第二个前提切实其实过剩。最少应当用一个>=号兼并这两个前提或只保存恣意一个前提,
进步效力。

DELETET
FROM成就表T
WHEREF>(SELECTMIN(F)
FROM成就表ASI
WHEREI.先生ID=T.先生ID
ANDI.课程ID=T.课程ID
GROUPBYI.先生ID,I.课程ID
)

这类办法,基础上是办法一的相干子查询版本,懂得笛卡尔积的读者能会好了解些,而
且用到了统计函数,因而效力不是太高。仔细的读者会发明子查询里的GROUPBY子
句没有需要,往失落它应当会进步一些效力的。

关于DELETE语句的调试,有履历的程序员城市先用有害的SELECT临时取代伤害的
DELETE。比方:

SELECTL.*
--DELECTL临时正文失落
FROM"成就表"L
JOIN"成就表"R
ONL."先生ID"=R."先生ID"ANDL."课程ID"=R."课程ID"ANDL.F>R.F

如许,极年夜地减小了在线数据被偶然损坏的大概性,固然数据提早备份也很主要。同理
UPDATE和INSERT写操纵也应照此行事。从数据库道理的干系运算的角度来看INSERT、
UPDATE和DELETE这些写操纵都属于典范的"选择(Selection)"运算,UPDATE和INSERT
并且仍是"投影(Projection)"运算,它们都是这些干系运算的"写"使用的体现情势。
实在,查询的目标也原本不过就是扫瞄、删除、更
新或拔出。一般写操纵也比读操纵损耗更年夜,假如索引过量,只会下降效力。

选择"子查询"仍是"毗连"在效力是有不同的,但最关头的不同仍是体现在查询的了局
集的读写性上,开辟职员在写一个"只读"使用的查询纪录集时,"子查询"和"毗连"各自
的效力就是应当起首思索的成绩,可是假如要完成"可写"使用的查询了局集,则不管是
相干仍是非相干子查询都是在庞大使用中难以免的。

以上办理计划中,应当说第一种办法,简便无效,很有创意,是值得保举的办法。固然,
最复杂的写法应当是:

DELETET
FROMT,TT1
WHERET.先生ID=T1.先生IDandT.课程ID=T.课程IDandT.F<T1.F

实在这就是办法一的"尺度"(但的确实不是《ANSI/ISOSQL》尺度)毗连写法,以下各
题谜底为了便于读者了解,一样平常不接纳这类写法,这也是《ANSI/ISOSQL》尺度所鼓
励的,JOIN的确更简单地表达表之间的干系,有乐趣的读者可自行改写。假如利用
"*="完成两表以上的外毗连时,要注重此时WHERE子句的AND前提是有按次的,尽
管《ANSI/ISOSQL》尺度不同意WHERE前提的按次影响查询了局,可是FROM子句
的各表毗连的按次能够影响查询了局。

2.列印各科成就最高和最低的相干纪录:(就是各门课程的最高、最低分的先生和先生)
课程ID,课程称号,最高分,先生ID,先生姓名,教员ID,教员姓名,最低分,先生ID,先生姓名,教员ID,教员姓名

假如这道题如果仅仅求出各科成就最高分或最低分,则是一道十分复杂的题了:

SELECTL.课程ID,MAX(L.课程称号),MAX(L.成就)AS最高分,MIN(L.成就)AS最低分
FROM成就表L
GROUPBYL.课程ID

可是,刁钻的标题倒是要列出各科最高和最低成就的相干纪录,这也常常才是真正需求。
既然已选出各科最高和最低分,那末,剩下的就是把先生和教员的信息并进这个了局
集。假如照如许写下往,十分贫苦,由于要增加的字段太多了,很快就使代码变得难于
办理。仍是换个思绪吧:

SELECTL.课程ID,L.课程称号,L.[成就]AS最高分,L.[先生ID],L.[先生姓名],L.[教员ID],L.[教员姓名]
,R.[成就]AS最低分,R.[先生ID],R.[先生姓名],R.[教员ID],R.[教员姓名]
FROM成就表L
JOIN成就表ASRONL.[课程ID]=R.[课程ID]
WHEREL.[成就]=(SELECTMAX(IL.[成就])
FROM成就表AS[IL]
WHEREL.[课程ID]=IL.[课程ID]
GROUPBYIL.[课程ID]
)
AND
R.[成就]=(SELECTMIN(IR.[成就])
FROM成就表AS[IR]
WHERER.[课程ID]=IR.[课程ID]
GROUPBYIR.[课程ID]
)

乍一看谜底,仿佛很庞大,实在假如把握了机关交织透视表的基础办法和相干子查询的
常识,成绩水到渠成。因为最低和最高分都是针对课程信息的,该谜底奇妙地把课程信
息兼并到了最高分的数据会合,固然也能够兼并到最低分中。代码中规中矩,作风很好,
可读性也是不错的。

3.按均匀成就从高到低按次,列印一切先生的四门(数学,语文,英语,政治)课程成就:(就是每一个先生的四门课程的成就单)
先生ID,先生姓名,数学,语文,英语,政治,无效课程数,无效均匀分
(注:无效课程即在T表中有该先生的成就纪录,如不分明可不列印"无效课程数"和"无效均匀分")

必要申明的是:标题之以是明白提出"四门(数学,语文,英语,政治)课程"是有事理的,
由于完成时,切实其实没法制止使原基础表中的行上的数据的值影响列,这又是一个典范的
"行变列"的相干子查询:

SELECT先生ID,MAX(先生姓名)AS先生姓名,
(SELECT成就FROM成就表WHERE先生ID=T.先生IDAND课程ID=K1)AS数学,
(SELECT成就FROM成就表WHERE先生ID=T.先生IDAND课程ID=K2)AS语文,
(SELECT成就FROM成就表WHERE先生ID=T.先生IDAND课程ID=K3)AS英语,
(SELECT成就FROM成就表WHERE先生ID=T.先生IDAND课程ID=K4)AS政治,
COUNT(*)AS无效课程数,AVG(T.成就)AS均匀成就
FROM成就表AST
GROUPBY先生ID
ORDERBY均匀成就

这能够说也是一个很礼貌的解法,在这类使用场所,子查询要比连接代码可读性强很多。
假如数据库引擎以为把它剖析成连接更好,那就由它往吧,实在原本相干子查询也一定含有毗连。
这里再增补一下,在实践使用中假如再加一张表Ranks(Rank,MinValue,MaxValue):

┌─────┬─────┬─────┐
│Rank│MinValue│MaxValue│
├─────┼─────┼─────┤
│A│90│100│
├─────┼─────┼─────┤
│B│80│89│
├─────┼─────┼─────┤
│C│70│79│
├─────┼─────┼─────┤
│D│60│69│
├─────┼─────┼─────┤
│E│0│59│
└─────┴─────┴─────┘

就能够完成一个十分有有用代价的使用:

select先生ID,MAX(先生姓名)as先生姓名
,(select成就from成就表twhere先生ID=T0.先生IDand课程ID=K1)as数学
,(SELECTmax(Rank)fromRanks,成就表t
wheret.成就>=Ranks.MinValue
andt.成就<=Ranks.MaxValue
andt.先生ID=T0.先生IDandt.课程ID=K1
)as数学级别
,(select成就from成就表twhere先生ID=T0.先生IDand课程ID=K2)as语文
,(SELECTmin(Rank)
fromRanks,成就表t
wheret.成就>=Ranks.MinValue
andt.成就<=Ranks.MaxValue
andt.先生ID=T0.先生IDandt.课程ID=K2
)as语文级别
,(select成就from成就表twhere先生ID=T0.先生IDand课程ID=K3)as英语
,(SELECTmax(Rank)
fromRanks,成就表t
wheret.成就>=Ranks.MinValue
andt.成就<=Ranks.MaxValue
andt.先生ID=T0.先生IDandt.课程ID=K3
)as英语级别
,(select成就from成就表twhere先生ID=T0.先生IDand课程ID=K4)as政治
,(SELECTmin(Rank)
fromRanks,成就表t
wheret.成就>=Ranks.MinValue
andt.成就<=Ranks.MaxValue
andt.先生ID=T0.先生IDandt.课程ID=K4
)as政治级别
,count(*),avg(t0.成就)
,(SELECTmax(Rank)
fromRanks
whereAVG(T0.成就)>=Ranks.MinValue
andAVG(T0.成就)<=Ranks.MaxValue
)AS均匀级别
from成就表t0
groupby先生ID

这里外表上利用了不等毗连,再细心想一想,Ranks表中每笔记录的区间是没有交集的,
实在也能够以为是等值毗连,如许的表计划无疑存在着优秀的扩大性,假如标题只需求

列印(先生ID,先生姓名,无效课程数,无效均匀分,均匀分级别):

select先生ID,MAX(先生姓名)as先生姓名,count(*),avg(t0.成就)
,(SELECTmax(Rank)
fromRanks
whereAVG(T0.成就)>=Ranks.MinValue
andAVG(T0.成就)<=Ranks.MaxValue
)AS均匀级别
fromTasT0
groupby先生ID

则如许的办理计划就对照周全了。

回到原题,再先容一个对照取巧的举措,仅需一个复杂分组查询便可办理成绩,有履历的读者大概已想到了
,那就是CASE:

SELECT先生ID,MIN(先生姓名),
SUM(CASE课程IDWHENK1THEN成就ELSE0END)AS数学,
SUM(CASE课程IDWHENK2THEN成就ELSE0END)AS语文,
SUM(CASE课程IDWHENK3THEN成就ELSE0END)AS英语,
SUM(CASE课程IDWHENK4THEN成就ELSE0END)AS政治,
COUNT(*)AS无效课程数,AVG(T.成就)AS均匀成就
FROM成就表AST
GROUPBY先生ID
ORDERBY均匀成就DESC

固然大概初看谜底感到有点怪,实在很好了解,可读性其实不低,效力也很高。但它不克不及
像前一个谜底那样,在成就中辨别出某一门课这个先生事实是缺考(NULL),仍是真得
零分。这个解法充实使用了CASE语句举行数据分类的感化:CASE将成就按课程分
成四类,SUM用来消往过剩的0。

SELECT[T].[先生ID],MAX([T].[先生姓名])AS先生姓名,
MAX([T1].[成就])AS数学,
MAX([T2].[成就])AS语文,
MAX([T3].[成就])AS英语,
MAX([T4].[成就])AS政治,
COUNT([T].[课程ID])AS无效课程数,
(ISNULL(MAX([T1].[成就]),0)+
ISNULL(MAX([T2].[成就]),0)+
ISNULL(MAX([T3].[成就]),0)+
ISNULL(MAX([T4].[成就]),0))/COUNT([T].[课程ID])AS无效均匀分
FROM成就表T
LEFTJOIN成就表AS[T1]ON[T].[先生ID]=[T1].[先生ID]AND[T1].[课程ID]=K1
LEFTJOIN成就表AS[T2]ON[T].[先生ID]=[T2].[先生ID]AND[T2].[课程ID]=K2
LEFTJOIN成就表AS[T3]ON[T].[先生ID]=[T3].[先生ID]AND[T3].[课程ID]=K3
LEFTJOIN成就表AS[T4]ON[T].[先生ID]=[T4].[先生ID]AND[T4].[课程ID]=K4
GROUPBY[T].[先生ID]
ORDERBY无效均匀分DESC

这个办法是相称正统的连接解法,只管写起来贫苦了些,但仍是不难了解的。再从有用
角度思索一下,实在需求常常不是象本题明白提出"列印四门(数学,语文,英语,政治)
课程"如许的绝对静态的需求,该是静态SQL大显神通的时分了,很分明办法一的写法
无疑是使用程序机关静态SQL的最好选择,固然另两个SQL纪律仍是挺分明的,一样
不难机关。以CASE版谜底为例:先用一个游标遍历,掏出一切课程凑成:
SUM(CASE课程IDWHEN课程称号THEN成就ELSE0END)AS课程称号情势,
再补上SELECT和FROM、WHERE等需要前提,一个天生静态成就单的SQL就出生了,
只需再由相干程序挪用实行便可,如许就能够算一个更完美的办理计划了。

实在,最相似的典范使用是在主、细干系中的主表投影中完成细表的汇总统计行,
比方两张表:
Master(F,f1,f2...)一对多Details(F,f3,f4...)
SELECT*
,(SELECTCOUNT(*)
FROMDetails
WHEREMaster.F=Details.F
)
,(SELECTSUM(F3)
FROMDetails
WHEREMaster.F=Details.F
)
FROMMaster

4.按各科不屈均成就从低到高和合格率的百分数从高到低按次,统计并列印各科均匀成就和不合格率的百分数(用"N行"暗示):
(就是剖析哪门课程难)
课程ID,课程称号,均匀成就,合格百分比
SELECT课程ID,MAX(课程称号)AS课程称号,AVG(成就)AS均匀成就
,str(100*SUM(CASEWHEN成就>=60THEN1ELSE0END)/COUNT(*))+%AS合格百分比
FROM成就表T
GROUPBY课程ID
ORDERBY合格百分比DESC

这道题应当说是算复杂的了,就是用"行"来供应体现情势的。只需想分明要对数据如
何分组,取统计会萃函数,就高枕无忧了。

5.列印四门课程均匀成就和合格率的百分数(用"1行4列"暗示):(就是剖析哪门课程难)
数学均匀分,数学合格百分数,语文均匀分,语文合格百分数,英语均匀分,英语合格百分数,政治均匀分,政治合格百分数

这道题实在就是上一题的"列"体现情势版本,相对上一题,本题是静态的,由于本题
同第三题一样使用行上的数据机关了列,要完成扩大必需再使用别的的程序机关静态
SQL:

SELECTSUM(CASEWHEN课程ID=K1THEN成就ELSE0END)/SUM(CASE课程IDWHENK1THEN1ELSE0END)AS数学均匀分
,100*SUM(CASEWHEN课程ID=K1AND成就>=60THEN1ELSE0END)/SUM(CASEWHEN课程ID=K1THEN1ELSE0END)AS数学合格百分数
,SUM(CASEWHEN课程ID=K2THEN成就ELSE0END)/SUM(CASE课程IDWHENK2THEN1ELSE0END)AS语文均匀分
,100*SUM(CASEWHEN课程ID=K2AND成就>=60THEN1ELSE0END)/SUM(CASEWHEN课程ID=K2THEN1ELSE0END)AS语文合格百分数
,SUM(CASEWHEN课程ID=K3THEN成就ELSE0END)/SUM(CASE课程IDWHENK3THEN1ELSE0END)AS英语均匀分
,100*SUM(CASEWHEN课程ID=K3AND成就>=60THEN1ELSE0END)/SUM(CASEWHEN课程ID=K3THEN1ELSE0END)AS英语合格百分数
,SUM(CASEWHEN课程ID=K4THEN成就ELSE0END)/SUM(CASE课程IDWHENK4THEN1ELSE0END)AS政治均匀分
,100*SUM(CASEWHEN课程ID=K4AND成就>=60THEN1ELSE0END)/SUM(CASEWHEN课程ID=K4THEN1ELSE0END)AS政治合格百分数
FROM成就表T

这一句看起来很长,但实践上是最典范的CASE使用,很有用的数据剖析手艺。先将原
表中的成就一列一连投影8次备用于四门分歧课程,充实使用CASE和数据的值域
[k1,k2,k3,k4]来分别数据,再使用SUM()[1+...+1]完成了看似原本应
该用COUNT(*)的计数器的功效,这内里不要说连接和子查询,乃至连Groupby分组
的陈迹都找不到!假如读起来费劲,完整能够先只保存一个字段,绝对好了解些,看懂后
一一补全。本题也能够算一个"行变列"的交织透视暗示例吧!别的,"行"相对"列"
是静态的,"行"是绝对无穷的,"列"是绝对无限的,"行"的增删是使用级的,可"随便"增
删,"列"的增删是办理级的,不要容易变化!

6.按分歧先生所教分歧课程均匀分从高到低列印:(就是剖析哪一个先生的哪一个课程程度高)
教员ID,教员姓名,课程ID,课程称号,均匀分

SELECT教员ID,MAX(教员姓名)AS教员姓名,课程ID,MAX(课程称号)AS课程称号,AVG(成就)AS均匀成就
FROM成就表T
GROUPBY课程ID,教员ID
ORDERBYAVG(成就)DESC

这道题切实其实没啥好说的,就算闭着眼,不下手,谜底也应信口开河!
假如均匀分按往失落一个最高分和一个最低分后获得,则也不难写出:

SELECT教员ID,MAX(教员姓名),课程ID,MAX(课程称号)AS课程称号--,AVG(成就)AS均匀成就
,(SUM(成就)
-(SELECTMAX(成就)
FROM成就表
WHERE课程ID=T1.课程IDAND教员ID=T1.教员ID)
-(SELECTMIN(成就)
FROM成就表
WHERE课程ID=T1.课程IDand教员ID=T1.教员ID))
/CAST((SELECTCOUNT(*)-2
FROM成就表
WHERE课程ID=T1.课程IDAND教员ID=T1.教员ID)ASFLOAT)AS均匀分
FROM成就表AST1
WHERE(SELECTCOUNT(*)-2
FROM成就表
WHERE课程ID=T1.课程IDAND教员ID=T1.教员ID)>0
GROUPBY课程ID,教员ID
ORDERBY均匀分DESC
********************************************************************************************
7.列印数学成就第10名到第15名的先生成就单
或列印均匀成就第10名到第15名的先生成就单
[先生ID],[先生姓名],数学,语文,英语,政治,均匀成就

假如只思索一门课程,如:数学成就,十分复杂:
selectTop5*
fromT
where课程id=K1
and成就notin(selecttop15成就
fromT
orderby成就desc
)
orderby成就desc
union
select*
fromT
where课程id=K1
and成就notin(selecttop10成就
fromT
orderby成就desc
)
and成就in(selecttop15成就
fromT
orderby成就desc
)
orderby成就desc

从逻辑上说,第10名到第15名就是从原前15名,"再"挑出前5名不要,保存剩下
的5名。第二种写法是夙昔15名里挑出不属于原前10名的纪录,把两个数据集做
一个差,因而要多用一个
子查询,效力绝对较低,它,假如要有《ANSI/ISOSQL》的EXCEPT
关头字就是最幻想的了。

这类技能在数据"分页"的使用中常常使用,只需遵守以下准绳便可:

SELECTTop@PageSize*
FROMT
WHERESortFieldNOTIN(SELECTTOP@PageSize*@PageiSortField
FROMT
ORDERBYSortField
)
ORDERBYSortField

至此,该题考查的次要目标已到达。至于列印了了成就单:
[先生ID],[先生姓名],数学,语文,英语,政治,均匀成就后面也有相似的标题,做起来
的确贫苦,因而上面仅供应参考谜底,就不赘述了:

SELECTDISTINCTtop5
[成就表].[先生ID],
[成就表].[先生姓名]AS先生姓名,
[T1].[成就]AS数学,
[T2].[成就]AS语文,
[T3].[成就]AS英语,
[T4].[成就]AS政治,
ISNULL([T1].[成就],0)+ISNULL([T2].[成就],0)+ISNULL([T3].[成就],0)+ISNULL([T4].[成就],0)as总分
FROM[成就表]
LEFTJOIN[成就表]AS[T1]
ON[成就表].[先生ID]=[T1].[先生ID]AND[T1].[课程ID]=k1
LEFTJOIN[成就表]AS[T2]
ON[成就表].[先生ID]=[T2].[先生ID]AND[T2].[课程ID]=k2
LEFTJOIN[成就表]AS[T3]
ON[成就表].[先生ID]=[T3].[先生ID]AND[T3].[课程ID]=k3
LEFTJOIN[成就表]AS[T4]
ON[成就表].[先生ID]=[T4].[先生ID]AND[T4].[课程ID]=k4
WHEREISNULL([T1].[成就],0)+ISNULL([T2].[成就],0)+ISNULL([T3].[成就],0)+ISNULL([T4].[成就],0)
NOTIN
(SELECT
DISTINCT
TOP15WITHTIES
ISNULL([T1].[成就],0)+ISNULL([T2].[成就],0)+ISNULL([T3].[成就],0)+ISNULL([T4].[成就],0)
FROM[成就表]
LEFTJOIN[成就表]AS[T1]
ON[成就表].[先生ID]=[T1].[先生ID]AND[T1].[课程ID]=k1
LEFTJOIN[成就表]AS[T2]
ON[成就表].[先生ID]=[T2].[先生ID]AND[T2].[课程ID]=k2
LEFTJOIN[成就表]AS[T3]
ON[成就表].[先生ID]=[T3].[先生ID]AND[T3].[课程ID]=k3
LEFTJOIN[成就表]AS[T4]
ON[成就表].[先生ID]=[T4].[先生ID]AND[T4].[课程ID]=k4
ORDERBYISNULL([T1].[成就],0)+ISNULL([T2].[成就],0)+ISNULL([T3].[成就],0)+ISNULL([T4].[成就],0)DESC)

最初还要多说一句:一样平常TOP关头字与ORDERBY子句适用才有真正意义。
根据Evans的调查报告,“MySQL的使用在未来将继续呈成长趋势。”
愤怒的大鸟 该用户已被删除
沙发
发表于 2015-1-20 05:07:46 | 只看该作者
在select语句中可以使用groupby子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集。
灵魂腐蚀 该用户已被删除
板凳
发表于 2015-1-25 12:29:59 | 只看该作者
比如,MicrosoftSQLServer2008的某一个版本可以满足现在的这个业务的需要,而且价格还比Oracle11g要便宜,那么这一产品就是适合的。
若天明 该用户已被删除
地板
发表于 2015-2-2 22:04:57 | 只看该作者
光写几个SQL实在叫无知。
谁可相欹 该用户已被删除
5#
发表于 2015-2-8 09:18:14 | 只看该作者
外键的级联更能扩展可能大部分的同行在设计OLTP系统的时候都不愿意建立外键,都是通过程序来控制父子数据的完整性。
爱飞 该用户已被删除
6#
发表于 2015-2-25 08:43:21 | 只看该作者
一个是把SQL语句写到客户端,可以使用DataSet进行加工;
变相怪杰 该用户已被删除
7#
发表于 2015-3-7 18:16:24 | 只看该作者
习惯敲命令行的朋友可能会爽一些。但是功能有限。适合机器跑不动SQLServerManagementStudio的朋友使用。
兰色精灵 该用户已被删除
8#
发表于 2015-3-15 11:17:32 | 只看该作者
是要和操作系统进行Socket通讯的场景。否则建议慎重!
飘飘悠悠 该用户已被删除
9#
发表于 2015-3-22 00:12:43 | 只看该作者
是要和操作系统进行Socket通讯的场景。否则建议慎重!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 21:10

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表