order by 子句的使用

本文详细介绍了如何在数据库中创建、插入、删除和更新学生、课程及选修表,并通过具体实例展示了这些操作的过程,包括主键、外键的设置及各种完整性的验证。
--数据库基本表的创建,插入,删除,更新操作
--建立一个"学生"表
--学生的学号:Sno,类型是char(9)-->因为学生的学号是9位的定长的字符串;
--学生的姓名:Sname,类型是varchar2(8)-->因此可以是2,3,4汉字,而本数据库中一个汉字对应两个字符;
--学生的年龄:Sage,类型是smallint-->smallint占用的是两个字节,表示数的范围是,-32,768-->32,767;
--学生的性别:Ssex,类型是char(2)-->学生的性别只有两种情况,'男'或者'女',因此使用2位的定长字符串表示;
--学生的所属系别:Sdept,类型是varchar2(4)-->学生所属系别的长度是不确定的,假设最长4个字符;
--学生表的主键为学生的学号;
create table Student
(
       Sno char(9) primary key,
       Sname varchar2(8),
       Ssex char(2) not null,
       Sage smallint not null,
       Sdept varchar2(4) not null
);

--创建学生"课程"表
--课程的课程号:Cno,类型是char-->假设课程号是4位的定长字符;
--课程的课程名:Cname,类型是varchar2-->首先课程的名字是一个字符串,假设课程名字最多有10个汉字,最多含有20个字符组成;
--课程的先行课程号:Cpno,类型是char-->这个属性的数据类型应该和课程号的数据类型是一致的;
--课程的学分:Ccredit,类型为smallint-->课程的学分是一个小正整数;
--学生"课程"表中的主键是Cno;
--学生"课程"表中的外键为Cpno;课程表中的Cpno引用自课程表中的Cno;
create table Course
(
       Cno char(4) primary key,
       Cname varchar2(20) not null,
       Cpno char(4),
       Ccredit smallint not null,
       foreign key(Cpno) references Course(Cno)
);

--创建学生"选修"表
--学生的学号Sno,类型为char(9)-->学号的长度是9个数字的定长字符;
--学生的课程号Cno,类型为char(4)-->课程号的长度是4个数字的定长字符;
--学生的成绩Grade,类型为smallint-->这个整数在0->100之间的数字;
--选修表的主键:Cno和Sno的组合;
--选修表的外键:选修表中的Sno引用自学生表Student中的学号Sno;选修表中的Cno引用自学生表Courses中的课程号Cno;
create table SC
(
       Sno char(9),
       Cno char(4),
       Grade smallint,
       primary key(Sno,Cno),
       foreign key(Sno) references Student(Sno),
       foreign key(Cno) references Course(Cno)
);

--查询到当前数据库的字符集,
--如果value=ZHS16GBK,那么一个汉字占用2个字节,即一个汉字占用2个字符的大小;
--如果value=AL32UTF8,那么一个汉字占用3个字节,即一个汉字占用3个字符的大小;
select * from v$nls_parameters t where t.PARAMETER='NLS_CHARACTERSET';
alter user scott account unlock;
alter user sys account unlock;
alteruseruser_name account unlock identifiedby  new_password;
--查询的结果显示的value = ZHS16GBK,那就说明在本数据库中一个汉字是占用两个字节的.

--向学生表中插入数据
insert into Student values('201215121','李勇','男',20,'CS');
insert into Student values('201215122','刘晨','女',19,'CS');
insert into Student values('201215123','王敏','女',18,'MA');
insert into Student values('201215125','张立','男',19,'IS');

--违背实体的完整性
insert into Student values('201215121','李白','男',20,'CS');
insert into Student values('201215122','刘备','女',19,'CS');

--违背实体的完整性
insert into Student values(null,'张三','男',19,'CS');
insert into Student values(null,'李四','男',20,'IS');

--违背用户定义的完整性
insert into Student values('201215126','张立','男',null,'IS');
insert into Student values('201215126','张立',null,30,'IS');

--查询学生的全部信息
select * from Student;

--删除学生表
drop table Student;

--向课程表中插入数据
--注意插入数据时,可能会发生违背参照的完整性-->因为Cpno字段的值可能在表中还没有被插入;
--注意插入数据式,还可能发生违背实体的完整性-->因为我们插入了一行之后,再次插入,主码和表中的重复;
insert into Course values('2','数学',null,2);
insert into Course values('6','数据处理',null,2);
insert into Course values('4','操作系统','6',3);
insert into Course values('7','PASCAl语言','6',4);
insert into Course values('5','数据结构','7',4);
insert into Course values('1','数据库','5',4);
insert into Course values('3','信息系统','1',4);

--违背了实体的完整性约束
insert into Course values('1','数据库','5',5);
insert into Course values('3','信息系统','1',4);

--违背了实体的完整性
insert into Course values(null,'数据库','5',4);
insert into Course values(null,'数据结构','7',4);

--违背了参照的完整性
insert into Course values('8','数据结构','20',4);
insert into Course values('9','数据结构','11',4);

--违背了用户自定义完整性
insert into Course values('10','数据结构','7',null);
insert into Course values('13','操作系统','6',null);

--说明在不违背子表中外码的值来自父表中主码已有的值的前提下,外码的值可以为空
insert into Course values('2','数学',null,2);
insert into Course values('6','数据处理',null,2);

--对课程表进行的查询操作
select * from Course;

--删除课程表
drop table Course;

--向选修表中插入数据
--在对选修表中的数据进行插入的时候,插入的学号和插入的课程号必须是学生表中,课程表中已经出现的值;
--选修表中的主码是学号和课程号的的组合,这时候对单一的学号或者单一的课程号来看他们是可以重复的;
--在进行数据的插入的时候组成主码的一个或者多个属性列,都不能为空
insert into SC values('201215121','1',92);
insert into SC values('201215121','2',85);
insert into SC values('201215121','3',88);
insert into SC values('201215122','2',90);
insert into SC values('201215122','3',80);

--insert into SC values('201215122','1',90);

--违反参照的完整新,子表中外码的值不能是父表中主码中不存在的值
insert into SC values('201215122','9',100);
insert into SC values('201400644','1',70); 

--违背了实体的完整性,表中的主码的值必须是唯一的,不能够重复
insert into SC values('201215122','3',90);
insert into SC values('201215121','1',92);

--违背实体的完整性,组成主码的各个属性列的值不能为空
insert into SC values('201215122',null,90);
insert into SC values(null,'2',70);   

--对选修表进行的查询操作
select * from SC;     

--删除选修表基本表
drop table SC;
--order by子句的使用练习
--用户可以使用order by子句对查询结果按照一个或者多个属性列的升序(asc)或者降序(desc)排序
--默认情况下(不对升序或者降序进行指定的情况下)使用升序排序

--首先查询选修表中所有学生的选课情况
select Sno 学生学号 ,Cno 课程号,Grade 课程成绩
from SC;
--查询选修了3号课程的学生的学号及其成绩,查询结果按照分数的降序排序
select Sno 学生学号,Cno 课程号,Grade 课程成绩
from SC
where Cno='3'
order by Grade desc;

select Sno 学生学号,Cno 课程号,Grade 课程成绩
from SC
where Cno='3'
order by Grade;

--使用order by子句按照指定的字段进行排序的时候 ,默认情况下是按照升序进行排序的
select Sno 学生学号,Cno 课程号,Grade 课程成绩
from SC
where Cno='3'
order by Grade asc;

--对于空值,排序时显示的次序是由具体的数据库管理系统来进行决定的,例如按照升序排序的时候
--含空值的元组最后显示,按照降序排序,空值的元组最先显示,各个系统的实现可以不同,只要形成统一的就可以

--那么oracle数据库对于空值是如何进行处理的呢?
--查询学号为201215122的学生的学号,学生选修课程的课程号,以及课程成绩,并且按照课程成绩分数的升序进行排序
select Sno 学生学号,Cno 选修课程号,Grade 课程分数
from SC
where Sno='201215122'
order by Grade asc;

select Sno 学生学号,Cno 选修课程号,Grade 课程分数
from SC
where Sno='201215122'
order by Grade desc;

--该SQL语句说明oracle 数据库管理系统采用的规则是:当按照某个字段进行升序排序时,将含有空值的元组
--排在最后一行;档按照某个字段进行降序排序的时候,将含有空值的元组排在第一行;

--查询全体学生情况,查询的结果按照所在院系的系号的升序排序,同一个系中的学生按照年龄的降序排列
select Sno 学生学号,Sname 学生姓名,Ssex 学生性别,Sage 学生年龄,Sdept 学生院系
from Student
order by Sdept asc,Sage desc;
<think>嗯,用户现在问的是关于SQL查询语句中ORDER BY子句的正确使用问题,提供的四个选项需要判断哪个是正确的。首先,我需要回忆一下ORDER BY的相关知识点,然后逐一分析选项。 首先看选项A:“如果未指定排序字段,则默认按递增排序”。这里有个疑问,ORDER BY子句如果未指定排序方式的话,默认是ASC还是DESC呢?根据SQL标准,默认确实是升序(ASC),所以如果用户没有指定,默认是按递增排序的。不过,这里有个前提,就是用户必须指定了排序字段。但是选项A提到的是“未指定排序字段”,这可能有歧义。比如,是否整个ORDER BY子句都没写,还是指没有明确写ASC或DESC?如果是前者,那整个查询就没有排序,自然没有默认排序的说法。所以选项A可能存在表述问题,可能不正确。 然后是选项B:“数据表的字段都可用于排序”。这里需要考虑的是,是否表中的所有字段都可以用在ORDER BY子句中。一般来说,只要字段在表中存在,就可以用于排序,但如果有使用DISTINCT或者聚合函数等情况,可能会限制可用字段。比如,当SELECT子句用了DISTINCT,那么ORDER BY的字段必须是SELECT中的字段。但选项B没有说明这种情况,所以是否正确需要看具体情况。不过题目中的选项B是否定还是肯定呢?原题中的选项B是否定吗?根据用户提供的选项,B的描述是“数据表的字段都可用于排序”,如果原表中的字段在ORDER BY中都可以使用,那是否正确呢?假设没有其他限制条件的话,应该是正确的,但如果有DISTINCT或GROUP BY等,可能会有影响。但选项B的表述是否正确需要更仔细分析。 选项C:“如果在SELECT子句使用了DISTINCT关键字,则排序字段必须出现在查询结果中”。根据SQL标准,当使用DISTINCT时,ORDER BY的字段必须是SELECT列表中的字段,否则可能导致错误,因为DISTINCT可能会消除重复行,而排序的字段如果不在结果集中,可能会引起歧义。例如,如果SELECT DISTINCT column1,但ORDER BY column2,而column2不在SELECT中,这时某些数据库会报错。因此选项C是正确的。 选项D:“联合查询不允许使用ORDER BY子句”。联合查询(UNION)实际上可以使用ORDER BY,但要注意的是ORDER BY必须放在最后一个SELECT语句之后,对整个联合结果进行排序。所以选项D是错误的。 现在需要判断这四个选项中哪个正确。根据分析,选项C是正确的,而用户提供的选项中正确答案是否选项C呢?用户之前的问题显示他们的答案被判定为错误,但当前的问题可能需要重新评估。不过根据当前分析,选项C是正确的,而其他选项可能存在错误。 不过需要再次确认每个选项的具体情况。比如选项B是否正确?如果数据表的字段都可用于排序,那么即使不在SELECT子句中?例如,假设有一个表有字段A和B,在查询中SELECT A,然后ORDER BY B,这是否允许?在标准SQL中,如果查询中没有DISTINCT、GROUP BY或聚合函数,是允许的,即使B不在SELECT列表中。但如果有DISTINCT,则不行。因此选项B的表述是否正确?题目中的选项B是否定是否定的条件吗?比如“数据表的字段都可用于排序”是否绝对正确?当存在DISTINCT或GROUP BY时可能不行,但题目中的选项B没有说明这些情况,所以可能不正确。因此选项B的说法是错误的,因为是否可用取决于查询的其他部分,比如是否包含DISTINCT、GROUP BY等,所以选项B的表述过于绝对,不正确。 因此,正确的选项应该是选项C:“如果在SELECT子句使用了DISTINCT关键字,则排序字段必须出现在查询结果中”。</think>### **正确答案:C(如果在SELECT子句使用了DISTINCT关键字,则排序字段必须出现在查询结果中)** --- ### **关键解析** 1. **选项A**: - **错误**。如果未指定排序方式(`ASC`或`DESC`),默认按**递增排序(ASC)**,但前提是**必须明确指定了排序字段**。若完全未指定`ORDER BY`子句,则查询结果无固定顺序。 2. **选项B**: - **错误**。虽然数据表的字段通常可用于排序,但存在以下例外: - 如果查询使用了 `DISTINCT`、`GROUP BY` 或聚合函数,排序字段必须出现在 `SELECT` 子句或与分组字段相关联。 - 示例:`SELECT DISTINCT col1 FROM table ORDER BY col2` 会报错(若 `col2` 未在 `SELECT` 中出现)。 3. **选项C**: - **正确**。当使用 `DISTINCT` 时,`ORDER BY` 的字段必须在查询结果中,否则可能因语义冲突导致错误(如重复值被合并后无法对应未显示的排序字段)。 - 示例:`SELECT DISTINCT col1 FROM table ORDER BY col1`(合法);`SELECT DISTINCT col1 FROM table ORDER BY col2`(非法)。 4. **选项D**: - **错误**。联合查询(`UNION`)允许使用 `ORDER BY`,但需注意: - `ORDER BY` 必须放在最后一个 `SELECT` 子句之后,对整个联合结果排序。 - 示例: ```sql SELECT col1 FROM table1 UNION SELECT col1 FROM table2 ORDER BY col1; -- 合法 ``` --- ### **总结** - **核心规则**: - 使用 `DISTINCT` 时,`ORDER BY` 字段必须在 `SELECT` 子句中。 - 联合查询可排序,但需统一排序规则。 - **典型错误场景**: - 试图通过未显示的字段排序(如 `DISTINCT` 查询中排序字段未在结果集中)。 - 在联合查询的单个子句使用 `ORDER BY`(需统一放在最后)。 **注**:理解 `ORDER BY` 与 `DISTINCT`、`UNION` 的交互逻辑是避免语法错误的关键。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值