SQL_Q

本文提供了一系列SQL查询案例,包括统计分析、复杂条件筛选等高级技巧,适用于数据库管理和数据分析人员提升技能。

 

学生信息xs(xh,xm,xb,nl) 

成绩信息cj(xh,kch,cj) 

课程信息(kch,kcm)

1统计年龄在20到30的男女生的人数,显示性别,人数

2 为下列查询select xb,nl,count(xh)    from  xs  where  nl>=20  or  nl<=30

group  by  xb,nl;选择一个合适的题目

A查询男生人数,女生人数

B 统计各年龄段的男女生人数

C 统计所有年龄的男女生人数

D 统计每个年龄的男女生人数

 

3 查询需要补考的人,显示学号,姓名,课程号

4假定有表CJ(学号xh,姓名xm,课程号kch,成绩cj),解释下列查询

1)select xh,xm,kch  from  cj  group by   xh  having  max(cj)<60

2)select xh,xm,kch  from  cj  group by  xh,xm,kch  having min(cj)<60

3)select xh,xm,kch  from  cj  group by  xh,xm,kch  having max(cj)<60

4)  23是否有区别?

 

 

5 统计平均成绩在80以上的课程,显示课程号,课程名

 

6 找出同名的人,显示学号,姓名,性别,年龄

 

7 此语句select xh,xm,xb,nl from xs group by xh,xm,xb,nl having count(xm)>1

查询什么?

 

8  语句select xh,xm,xb,nl  from xs a,xs b where  a.xm=b.xm错在什么地方?

 

9  统计所有人(没有成绩的也要统计)的总分,显示学号,姓名,总分

select  * from       xs  left  join  cj  on  xs.xh=cj.xh;

select xs.xh,xm,cj  from xs  left  join  cj  on  xs.xh=cj.xh;

select  xs.xh,xm, sum(cj) from xs  left  join  cj  on  xs.xh=cj.xh

group by  xs.xh,xm;

 

 

1   -   n 怎么创建表?

m  -   n 怎么创建表

 

老师   学生两个实体没有任何关系?

假定是老师1 对学生n   ,要在学生的表中定义老师的编号做为外键,有什么意思?

假定是多对多,根据数据库设计范式,要将两个实体的主键提取出来,至少再产生一张表,请问将老师编号和学生编号放在一张表有什么用处?

 

 

 

1统计每个人的总分,显示学号,总分

select sid,sum(score) from sc  group by sid;

2 统计总分最高的人,显示学号

数据库第一范式:字段名称必须规范且不能相同

将查询做为数据源要符合数据库第一范式

select  sid,max(sum(score)) from sc group by sid;

 select  sid,max(sum(score)) from

 (

select sid,sum(score) from sc  group by sid

 );

select sid,sum(score) sid from sc group by sid;

select * from  (  select sid, sum(score) sid  from sc group by sid  );

方法一:

先查出最大总分

select  max(zf)  from  (select  sum(score)  zf  from sc  group by sid );

将每个人的总分和最大总分比较

select sid,sum(score) 总分  from sc  group by sid

having  sum(score)>=(  最大总分  );

方法二:

 将每个人的总分和所有人的总分比较(利用all关键字)

 

select sid,sum(score) 总分  from sc  group by sid

having  sum(score)>=all(select  sid,sum(score)   from sc  group by sid);执行结果( 

select sid,sum(score) 总分  from sc  group by sid

having  sum(score)>=all(select  sum(score)   from sc  group by sid);

 

 

3找出同名的人,显示学号,姓名,性别

select  distinct  a.* from  student  a, student b  

where  a.sname=b.sname  and  a.sid<>b.sid;

为什么要加distinct

学号

姓名

 

学号

姓名

1

张三

1

张三

2

张三

2

张三

3

张三

3

张三

用子查询演示找同名的学生

select   *  from student  where sname in (

select sname,count(*) from student group by sname

having  count(*)>1

);

select  a.* from student a,

(select sname from student group by sname having count(*)>1) b

where a.sname=b.sname;

4 找出选修3门课程以上,且平均分最高的人,显示学号

select sid from sc group by sid having  count(*)>=3

and avg(score)>=all(   select  avg(score) from sc group  by  sid        );

 

5 统计所有人(没有成绩的也要统计)的总分,显示学号,姓名,总分

左或右连接

 

不准使用左或右连接

select a.sid 学号,sname 姓名 ,sum(score) 总分 from student a,sc where a.sid=sc.sid group by a.sid,sname

union

select sid,sname ,0    from  student  where  sid  not  in ( 

 select   distinct  sid  from  sc

);

 

6 统计学过sc曹杨老师teacher课程course的人,显示学号,姓名student

select a.sid,sname from student a,sc,course b ,teacher c

 where a.sid=sc.sid  and sc.cid=b.cid and b.tid=c.tid and c.tname=’aaa’;

 

select a.sid,sname from student a ,sc  where a.sid=sc.sid 

and  cid  in  (

    select  b.cid  from  course b ,teacher  c  where  b.tid=c.tid  and  c.tname=’sss’     ) ; 

 

7  统计学过1001老师course.tid两门课程sc.cid  course.cid以上的人,显示学号sc.sid

select  sid,tid,sc.cid  from  sc, course   where  sc.cid=course.cid  and  tid=1001 ;

select   sid  from  sc  ,course  where sc.cid=course.cid  and  tid=1001

group by  sid   having count(*)>=2;

 

8 统计学过1001号老师所有课程的人,显示学号

提示:学生选1001老师的课的数量=1001老师带课的数量

select   sid  from  sc  ,course  where sc.cid=course.cid  and  tid=1001

group by  sid   having  count(*)=(  

   select   count(*)  from sc,course where sc.cid=course.cid and tid=1001  );

上述语句问题(                                     )

 

学号

课程号

成绩

 

课程号

课程名

老师号

1

1

 

1

 

1001

1

2

 

2

 

1001

2

1

 

3

 

1002

2

2

 

 

4

 

1002

 

 

 

 

5

 

1001

select   sid  from  sc  ,course  where sc.cid=course.cid  and  tid=1001

group by  sid   having  count(*)=(

   select   count(*)  from  course  where  tid=1001  );

 

9 统计学过1001号老师所有课程的人,显示学号,姓名

 

 

 

 

10  统计学过曹杨老师所有课程的人,显示学号,姓名

 

先统计每个学生选的每个曹杨老师的选课数量

再统计每个曹杨老师带课数量

然后这个两个数据源进行比对连接

 

只要符合某个曹杨,比如

学1    曹1   曹2 

学2    曹1

学3    曹2

 

 

<think>我们想要合并会话信息和对应的SQL语句,以便分析临时表空间的使用情况。在Oracle中,可以通过关联`v$session`、`v$tempseg_usage`和`v$sql`等动态性能视图来实现。 目标:显示每个会话的临时表空间使用情况,并关联到该会话正在执行的SQL语句。 步骤: 1. 从`v$tempseg_usage`视图中获取临时段的使用情况(包括会话地址、SQL_ID、使用的块数等)。 2. 关联`v$session`视图,通过会话地址(session_addr)或会话ID(sid)来获取会话的详细信息(如用户名、机器名、程序名等)。 3. 关联`v$sql`视图,通过SQL_ID来获取具体的SQL文本。 注意:一个会话可能执行多个SQL语句,而`v$tempseg_usage`会记录每个SQL语句使用的临时段。因此,我们通过SQL_ID关联到具体的SQL语句。 以下是一个查询示例,它将会话信息、临时表空间使用情况以及对应的SQL语句合并显示: ```sql SELECT s.sid, s.serial#, s.username, s.machine, s.program, s.status, s.logon_time, t.tablespace, t.contents, t.segtype, ROUND((t.blocks * p.value)/1024/1024, 2) AS temp_used_mb, t.sql_id, q.sql_text FROM v$tempseg_usage t JOIN v$session s ON t.session_addr = s.saddr JOIN v$sql q ON t.sql_id = q.sql_id CROSS JOIN v$parameter p WHERE p.name = 'db_block_size' AND t.blocks > 0; -- 只显示正在使用临时空间的 ``` 解释: - `v$tempseg_usage`:记录临时段的使用情况,包括会话地址(session_addr)、SQL_ID、使用的块数(blocks)、表空间名(tablespace)等。 - `v$session`:提供会话的详细信息,我们通过`session_addr`关联。 - `v$sql`:通过SQL_ID关联,获取SQL文本。 - `v$parameter`:用于获取数据库块大小(db_block_size),因为临时段使用的块数需要乘以块大小才能转换为字节(这里再转换为MB)。 注意:`v$tempseg_usage`中的blocks是使用临时表空间的块数,乘以块大小(db_block_size)得到字节数,再除以1024两次得到MB。 这个查询可以显示每个会话的临时表空间使用量(MB),并显示对应的SQL语句,方便我们分析是哪些SQL语句占用了大量的临时空间。 另外,由于一个会话可能同时执行多个SQL语句(每个SQL语句可能有多个临时段),所以一个会话可能会对应多行。 如果临时表空间使用过大,我们可以通过这个查询定位到具体的会话和SQL语句,然后进一步优化SQL或终止会话。 注意:在生产环境中执行此类查询时,要注意其性能影响,因为关联多个视图可能有一定的开销。 根据引用[2]中提到的,我们还可以通过其他方式监控临时表空间,但上述查询提供了会话和SQL级别的详细信息。 引用[1]提到临时表空间用于排序、哈希连接等操作,因此这些操作较多的SQL语句可能会占用大量临时空间。 引用[3][4][5]提到临时表的使用,在Oracle中,全局临时表(GTT)的数据存储在临时表空间中,所以如果会话中使用了临时表并且数据量较大,也会在临时表空间中占用空间。 如果查询结果中SQL_TEXT显示的是PL/SQL匿名块(如DECLARE BEGIN END),则可能是PL/SQL块中使用了临时表或执行了排序操作。 通过这个查询,我们可以监控当前数据库中哪些会话和SQL正在大量使用临时表空间,从而进行优化或管理。 相关问题: 1. 如何终止占用大量临时表空间的会话? 2. 如何优化使用大量临时表空间的SQL语句? 3. 临时表空间的使用与哪些数据库操作有关? 4. 如何监控临时表空间的历史使用情况?</think>要合并显示会话信息和对应的 SQL 语句以分析临时表空间使用情况,可通过以下 SQL 查询实现。该查询关联 Oracle 的关键动态性能视图,提供全面的分析视角: ```sql SELECT s.sid AS "会话ID", s.serial# AS "序列号", s.username AS "用户名", s.program AS "客户端程序", s.status AS "会话状态", t.tablespace AS "临时表空间", ROUND((t.blocks * p.value)/1024/1024, 2) AS "已用空间(MB)", t.sql_id AS "SQL_ID", q.sql_text AS "完整SQL语句", t.segtype AS "段类型" FROM v$session s JOIN v$tempseg_usage t ON s.saddr = t.session_addr JOIN v$sql q ON t.sql_id = q.sql_id CROSS JOIN v$parameter p WHERE p.name = 'db_block_size' AND t.blocks > 0 -- 只显示正在使用临时空间的会话 ORDER BY "已用空间(MB)" DESC; ``` ### 关键视图说明: 1. **`v$session`** 提供会话基础信息(SID, Serial#, 用户名等)[^2] 2. **`v$tempseg_usage`** 核心临时空间使用视图,包含: - `blocks`:已用数据块数量 - `tablespace`:临时表空间名 - `sql_id`:关联的 SQL 语句 ID - `segtype`:段类型(SORT/HASH/JOIN 等)[^1] 3. **`v$sql`** 通过 `sql_id` 关联获取完整 SQL 文本 4. **`v$parameter`** 获取 `db_block_size` 计算实际空间用量: $$ \text{实际空间(MB)} = \frac{\text{blocks} \times \text{db\_block\_size}}{1024 \times 1024} $$ ### 输出列说明: | 列名 | 说明 | 分析价值 | |------|------|----------| | 会话ID | 会话唯一标识 | 定位问题会话 | | 已用空间(MB) | 精确空间消耗 | 识别资源消耗TOP会话 | | SQL语句 | 完整SQL文本 | 分析SQL是否可优化 | | 段类型 | 操作类型(SORT/HASH等) | 判断优化方向[^1] | | 客户端程序 | 发起程序名(如JDBC) | 追踪应用来源 | ### 典型分析场景: 1. **定位高消耗SQL** ```sql -- 查找消耗超过100MB的排序操作 SELECT * FROM ( SELECT /*+ 嵌套子查询示例 */ ... ) -- 显示为SORT段类型且高空间消耗[^3] ``` 2. **识别异常会话** ```sql -- 状态为INACTIVE但仍占用临时空间 WHERE s.status = 'INACTIVE' AND t.blocks > 1000 ``` 3. **关联临时表操作** ```sql -- 创建会话级临时表(空间持续占用) CREATE GLOBAL TEMPORARY TABLE ... ON COMMIT PRESERVE ROWS; -- 显示为DATA段类型[^5] ``` ### 优化建议: 1. 定期运行此查询并保存结果到历史表 2. 对高频出现的SQL进行执行计划分析 3. 对使用`ON COMMIT PRESERVE ROWS`的临时表评估是否可改为事务级[^5] 4. 对排序/分组操作考虑增加索引优化 > 通过此关联分析,可精准定位临时表空间异常占用的源头,结合SQL优化或会话管理解决问题[^1][^2]。 --- **相关问题:** 1. 如何自动监控Oracle临时表空间的异常增长? 2. 哪些类型的SQL语句最容易导致临时表空间膨胀? 3. 临时表空间使用与PGA内存管理有何关联? 4. 如何区分临时表空间中排序段和临时表段的存储差异?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值