数据库
SELECT查询练习
--检索有学生重修的教师编号和姓名
USE school;
SELECT DISTINCT T1.gh AS '教师工号',T1.xm AS '教师姓名'
FROM
dbo.T AS T1
RIGHT JOIN
dbo.E AS E1
ON T1.gh=E1.gh
WHERE EXISTS
(
SELECT E2.xh
FROM dbo.E AS E2
WHERE
--学号一样
E2.xh=E1.xh AND
--课号也一样
E2.kh=E1.kh AND
--学期存在更小的
(
SUBSTRING(E2.xq,0,10)<SUBSTRING(E1.xq,0,10)
OR
(
SUBSTRING(E2.xq,0,10)=SUBSTRING(E1.xq,0,10)
AND
SUBSTRING(E2.xq,10,15)>SUBSTRING(E1.xq,10,15)
)
)
);
--检索有学生重修的教师编号和姓名
USE school;
SELECT DISTINCT E1.gh AS '教师工号',T1.xm AS '教师姓名'
FROM
(
dbo.T AS T1
RIGHT JOIN
dbo.E AS E1
ON T1.gh=E1.gh
INNER JOIN
dbo.E AS E2
ON
E1.xh=E2.xh AND
E1.kh=E2.kh AND
(
SUBSTRING(E2.xq,0,10)<SUBSTRING(E1.xq,0,10)
OR
(
SUBSTRING(E2.xq,0,10)=SUBSTRING(E1.xq,0,10)
AND
SUBSTRING(E2.xq,10,15)>SUBSTRING(E1.xq,10,15)
)
)
);
--查询选修了两门及以上课程的学生学号
USE school;
SELECT DISTINCT xh AS '学号'
FROM dbo.E
GROUP BY xh
HAVING COUNT(*)>1; --组过滤条件(组满足条件就输出,必须用聚合)
--查询选修了两门及以上课程的学生学号及选修门数,按门数降序,学号升序
USE school;
SELECT DISTINCT xh AS '学号',COUNT(*) AS '门数'
FROM dbo.E
GROUP BY xh
HAVING COUNT(*)>1
ORDER BY
2 DESC,
xh ASC;
--查询有三门以上课程90分以上的学生的学号以及90分以上的课程数
USE school;
SELECT xh AS '学号',COUNT(*) AS '90分以上课程数'
FROM dbo.E
WHERE zpcj>=90
GROUP BY xh
HAVING COUNT(*)>=3;
--输出有成绩在90分以上的学生的学号和选课门数
USE school;
SELECT xh AS '学号',COUNT(*) AS '选课门数'
FROM dbo.E
GROUP BY xh
HAVING MAX(zpcj)>=90; --分组以后,组内最高分>=90分
--查询所有成绩在80分以上的学生学号
USE school;
SELECT xh AS '学号'
FROM dbo.E
GROUP BY xh
HAVING MIN(zpcj)>=80; --分组以后,组内最低分>=80分
--查询有成绩在90分以上的学生学号
--①
USE school;
SELECT DISTINCT xh AS '学号'
FROM E
WHERE zpcj>=90;
--②
USE school;
SELECT xh AS '学号'
FROM E
WHERE zpcj>=90
GROUP BY xh;
--③
USE school;
SELECT xh AS '学号'
FROM dbo.E
GROUP BY xh
HAVING MAX(zpcj)>=90;
--MOV(mid,...)电影表
--CST(cid,...)演员表
--MC(mid,cid,...)电影-演员的关联表
--求参演演员超过10人,且这些演员中至少有两人还合作过其它电影的影片
USE movie;
SELECT *
FROM MOV
WHERE mid IN
(
SELECT mid
FROM MC AS MC0
GROUP BY mid
HAVING COUNT(*)>10
)
AND
EXISTS
(
SELECT *
FROM MC AS MC1, MC AS MC2
WHERE
MC1.cid!=MC2.cid
AND
MC1.mid=MC2.mid
AND
MC1.mid!=MOV.mid
AND
MC1.cid IN
(
SELECT MC3.cid
FROM MC AS MC3
WHERE MC3.mid=MOV.mid
)
AND
MC2.cid IN
(
SELECT MC3.cid
FROM MC AS MC3
WHERE MC3.mid=MOV.mid
)
);
--查询每个学生选课情况(包括没有选修课程的学生)
USE school;
SELECT S.xh AS '学号',S.xm AS '姓名',E.kh AS '课号',C.km AS '课名',E.xq AS '学期'
FROM
dbo.S
LEFT JOIN
dbo.E
ON S.xh=E.xh
LEFT JOIN
dbo.C
ON E.kh=C.kh;
--检索选了2次课的学生的学号与姓名
USE school;
SELECT S.xh AS '学号',S.xm AS '姓名',COUNT(*)
FROM
dbo.S
LEFT JOIN
dbo.E
ON S.xh=E.xh
GROUP BY S.xh,S.xm
HAVING
COUNT(*)=2;
--检索所有课程都选修的的学生的学号与姓名
--即查询SxE表中这样的学生:不存在[C表里的这样的课:本学生未选]
--即查询SxE表中这样的学生:不存在[C表中的这样的课:不存在[E表里的这个课,学号与本学生相同]]
USE school;
SELECT DISTINCT S0.xh AS '学号',S0.xm AS '姓名'
FROM
dbo.S AS S0
WHERE
NOT EXISTS
(
SELECT *
FROM dbo.C AS C0
WHERE
NOT EXISTS
(
SELECT *
FROM dbo.E AS E0
WHERE
E0.kh=C0.kh AND
E0.xh=S0.xh
)
);
--检索选修课程包含1106同学所学全部课程的学生学号和姓名
--即选择这样的学生:[1106号学生的所有课号集-选修的所有课号集]为空集
USE school;
SELECT S0.xh AS '学号',S0.xm AS '姓名'
FROM dbo.S AS S0
WHERE
NOT EXISTS
(
(
SELECT DISTINCT E1.kh
FROM dbo.E AS E1
WHERE E1.xh=1106
)
EXCEPT
(
SELECT DISTINCT E0.kh
FROM dbo.E AS E0
WHERE E0.xh=S0.xh
)
);
--查询每门课程中分数最高的学生学号和学生姓名,总评成绩
USE school;
SELECT MaxGradeTab.课程号,SETab.学号,SETab.姓名,SETab.总评成绩
FROM
(
SELECT S0.xh AS '学号',S0.xm AS '姓名',E0.zpcj AS '总评成绩'
FROM
dbo.S AS S0
INNER JOIN
dbo.E AS E0
ON S0.xh=E0.xh
) AS SETab
INNER JOIN
(
SELECT kh AS '课程号',MAX(zpcj) AS '最大总评'
FROM dbo.E
GROUP BY E.kh
) AS MaxGradeTab
ON SETab.总评成绩=MaxGradeTab.最大总评
ORDER BY
MaxGradeTab.课程号;
--查询年龄小于本学院平均年龄
--所有课程总评成绩都高于所选课程平均总评成绩
--(不存在[该学生这样的课程:不高于平均总评成绩])
--的学生学号、姓名和平均总评成绩
--按年龄排序
USE school;
SELECT
E0.xh AS '学号',
S0.xm AS '姓名',
(
SELECT AVG(E3.zpcj)
FROM dbo.E AS E3
WHERE E3.xh=S0.xh
) AS '平均总评成绩'
FROM
dbo.E AS E0
LEFT JOIN
dbo.S AS S0
ON E0.xh=S0.xh
WHERE
DATEDIFF(DAY,S0.csrq,'2018-1-1')<
(
SELECT AVG(DATEDIFF(DAY,S1.csrq,'2018-1-1'))
FROM dbo.S AS S1
WHERE S1.yxh=S0.yxh
)
AND
NOT EXISTS
(
(
SELECT *
FROM dbo.E AS E1
WHERE
E1.xh=S0.xh
AND
E1.zpcj<=
(
SELECT AVG(zpcj)
FROM dbo.E AS E2
GROUP BY E2.kh
HAVING E2.kh=E1.kh
)
)
)
ORDER BY S0.csrq;
硬件与并行
冯·诺依曼瓶颈
主存和CPU的分离限制了指令和数据访问的速率。
派生和合并
当一个线程开始时,从进程中派生(fork)出来,结束时合并(join)到进程中去。
写直达和写回
写直达:当CPU向cache写数据时,cache行会立即写入主存中。
写回:数据不是立即更新到主存,而是将发生数据更新的行标记为dirty,当发生高速缓存行替换时,dirty行更新入主存。
cache映射
①全相联:每个高速缓存行能够放置在cache中的任意位置。
②直接映射:每个高速缓存行在cache中有唯一位置。
③n路组相联:每个高速缓存行能放置到cache中n个不同区域位置的一个。即分组全相联。
交换空间
虚存机制使用的,那些暂时用不到的部分存储在辅存的某些块中,即存在交换空间中。
LIP指令级并行
通过让多个处理器或功能单元同时执行指令来提高性能的并行方式。
①流水线:将功能单元分阶段安排。
②多发射:让多条指令同时启动。
两类多发射
①静态多发射:功能单元在编译时调度。
②动态多发射:功能单元在运行时调度。一个支持动态多发射的处理器称为超标量。
预测和回退
在有多余的并行资源时,处理器可以对后面要执行哪个指令做预测,在预测上执行代码。
如果预测错误,则需要回退,但预测毕竟是用了多余的并行资源。
TLP线程级并行
通过执行不同线程来提高并行,TLP提供的是粗粒度的并行性,相比ILP,同时执行的程序基本单元(线程)比细粒度的程序单元(单条指令)更大或者更粗。
SMT同步多线程
通过允许多个线程同时使用多个功能单元来利用超标量处理器的性能。
SISD单指令流单数据流
一次执行一条指令,一次存取一个数据项。
SIMD单指令多数据流
通过对多个数据执行相同的指令从而实现在多个数据流上的操作,这种方式也叫数据并行。
MIMD多指令多数据流
系统支持同时多个指令流在多个数据流上操作。
共享内存系统
每个处理器能够访问每个内存区域,使用多核处理器,每个核都有私有的L1 Cache,而其它的Cache可以在核之间共享,也可以不共享。
①UMA一致内存访问:每个核访问内存中任何一个区域的时间都相同,容易编程。
②NUMA非一致内存访问:对与核直接连接的内存区域访问速度较快,不易于编程,但比UMA系统能使用更大容量的内存。
分布式内存系统
每个处理器有自己私有的内存空间,处理器-内存对之间通过互连网络相互通信。最广泛使用的分布式内存系统称为集群,通常认为一个集群有多个共享内存节点。
SMPD单程序多数据流
SMPD程序仅包含一段可执行代码,通过使用条件转移,使得执行时看起来是在不同处理器上执行不同的程序。
进程/线程分配依据
①负载均衡,②通信量尽可能小
动态线程和静态线程
①动态线程:有一个主线程,当请求到达主线程时,它会派生出工作线程来执行该请求,执行完后就会终止执行然后合并到主线程中。
②静态线程:主线程完成必须的设置后,派生出所有线程,在工作结束前所有的线程都存活。
并行程序的加速比
如果这个比等于核的数目p,那么称这个并行程序有 线性加速比。
并行程序的效率
阿姆达尔定律
除非一个串行程序几乎全部可以并行化,否则不论有多少核,通过并行化产生的加速比总是受到必须的串行时间的限制。