Oracle学习——sql1999连接、Oracle的set运算符、并集、交集、控制结果排序

本文深入解析SQL中的连接查询,包括交叉连接、自然连接、内连接、左外连接、右外连接及全外连接的语法与应用实例。同时,介绍了Oracle的集合操作符如UNION、UNION ALL、INTERSECT和MINUS的功能与使用场景。

SQL1999连接

连接查询新语法

SELECT table1.column_name,table2.column_name FROM table1
		[CROSS JOIN table2]  //交叉连接
[NATURAL JOIN table2] |	//自然连接
		[JOIN table2 USING (column_name)] |      //内连接
		[JOIN table2 ON (table1.column_name = table2.column_name)] |  //内连接
		[LEFT | RIGHT | FULL OUTER JOIN table2      //左外连接  右外连接 全(满)外连接
ON (table1.column_name = table2.column_name)];

交叉连接(了解即可)

用于生成两张表的笛卡尔集

	Select d.dname,e.ename,d.deptno,e.deptno 
		from dept d cross join emp e;

自然连接:特殊的等价连接,它将表中具有相同名称的列自动进行记录匹配
自然连接不必指定任何同等连接条件。(内连接中的一种)
语法:

	SELECT table1.column_name,table2.column_name
			FROM table1 NATURAL JOIN table2;

举例:查询员工名、工资以及所在部门名称。

	Select e.ename,e.sal,d.dname
			From emp e natural join dept d;


	9.5.3连接介绍	
		内连接(返回两张表完全满足连接条件的记录)

左连接:左表全部记录,右表满足条件记录。缺失的数据用null

右连接:与左连接相反 缺失的数据用null

完全外连接:两张表的全部内容相当于左连接和右连接并集去掉重复。

内连接

只返回两个表中相匹配的数据(满足条件的数据)
等值连接、非等值连接、自然连接都属于内连接。

用USING子句建立相等连接

Select e.ename,e.sal,d.dname from dept d join emp e using(deptno);

用on子句建立相等连接

Select e.ename,e.sal,d.dname from dept d join emp e on e.deptno=d.deptno;

左(外)连接:用于返回左表的全部记录,右表的满足条件的记录
LEFT[OUTER]JOIN

Select e.ename,e.sal,d.dname from dept d left join emp e on e.deptno = d.deptno;

右(外)连接:用于返回右表的全部记录,左表的满足条件的记录
RIGHT[OUTER]JOIN

Select e.ename,e.sal,d.dname from dept d right join emp e on e.deptno=d.deptno;

完全(外)连接:左表和右表的全部数据 FULL[OUTER] JOIN

Select e.ename,e.sal,d.dname from dept d full join emp e on e.deptno=d.deptno;

Oracle 的set运算符

集合操作符专门用于合并多条select语句的结果,包括4种:
第一种:UNION 并集:去掉重复数据,并按第一列的结果升序排序

举例:合并显示emp01表和emp02表所有雇员的部门编号、员工号、员工姓名
创建两张表:
第一张:部门号10-20的员工信息表

	 create table emp01
		As 
	 Select * from emp where deptno in (10,20);

第二张:部门号20-30的员工信息表

	create table emp02
		As 
	Select * from emp where deptno in (20,30);

那么求并集就是:

	Select deptno,emono,ename from emp01 
	Union 
	Select deptno,empno,ename from emp02;
	//注意 在这里因为是union所以部门号为20的不会显示两遍,重复的只显示一遍

UNION ALL 并集:不去掉重复数据,并不会对结果集排序

举例:合并显示emp01表和emp02表所有雇员的部门编号、员工号、员工姓名

	Select deptno,empno,ename from emp01 
	Union all
	Select deptno,empno,ename from emp02;
		//注意 在这里因为是union所以部门号为20的会显示两遍

INTERSECT交集:显示同时存在两个结果集中的数据,按第一列的结果集升序排序

举例:显示同时emp01表和emp02表的雇员的部门编号、员工号、员工姓名

	Select deptno,emono,ename from emp01 
	INTERSECT
	Select deptno,empno,ename from emp02;
		//注意 在这里显示的是部门号为20的员工的而信息。

MINUS 差集:显示第一个结果集中存在,而第二个结果集中不存在的数据。按第一列结果集进行升序排序
举例:显示emp01表中有emp02表中没有的雇员的部门编号、员工号、员工姓名

	Select deptno,emono,ename from emp01 
	MINUS
	Select deptno,empno,ename from emp02;
		//注意 在这里显示的是部门号为10的员工的而信息。

控制结果排序:当使用union、intersect和minus时,默认情况下会自动基于第一列进行升序排序,而当使用union all时不会进行排序,为了控制结果的排序顺序,可以使用order by子句

	Select deptno,emono,ename from emp01 
	Union all
	Select deptno,empno,ename from emp02;
	Order by 1;

注意
//order by 后面指定需要进行排序的列
//查询的两个表的列名相同时,可以用列名称
//查询两个表的列名不同时,要使用列位置(用数字表示)
//若是同SELECT *,order by 后面必须用数字

### 关于合的交集的相关算法 #### 1. **C++ 中的 STL 算法** 在 C++ 的标准模板库 (STL) 中,提供了 `set_union` 和 `set_intersection` 函数来分别计算两个有序合的交集。这些函数位于 `<algorithm>` 头文件中。 - 计算时,使用 `set_union` 将两个合中的所有唯一元素组合成一个新的合[^1]。 - 计算交集时,使用 `set_intersection` 提取出两个合中共有的元素。 以下是基于 C++ 的代码示例: ```cpp #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> setA = {1, 2, 3, 4}; std::vector<int> setB = {2, 3, 5, 6}; std::vector<int> unionResult; std::vector<int> intersectionResult; // std::set_union(setA.begin(), setA.end(), setB.begin(), setB.end(), std::back_inserter(unionResult)); // 交集 std::set_intersection(setA.begin(), setA.end(), setB.begin(), setB.end(), std::back_inserter(intersectionResult)); std::cout << "Union: "; for(auto num : unionResult){ std::cout << num << " "; } std::cout << "\nIntersection: "; for(auto num : intersectionResult){ std::cout << num << " "; } return 0; } ``` #### 2. **Python 手动实现交集算法** 尽管 Python 支持直接使用内置方法或运算符(如 `&` 或 `.intersection()`)快速获取两合的交集,但为了深入理解其工作原理,可以通过手动方式实现该逻辑[^2]。 下面是一个简单的手写版本: ```python def manual_intersect(set_a, set_b): result_set = [] # 转化为列表以便遍历 list_a = list(set_a) list_b = list(set_b) i, j = 0, 0 while i < len(list_a) and j < len(list_b): if list_a[i] == list_b[j]: result_set.append(list_a[i]) i += 1 j += 1 elif list_a[i] < list_b[j]: i += 1 else: j += 1 return set(result_set) # 示例调用 a = {1, 2, 3, 4} b = {2, 3, 5} print(manual_intersect(a, b)) # 输出应为 {2, 3} [^2] ``` #### 3. **顺序表实现合的操作** 对于更基础的数据结构——顺序表而言,也可以通过数组模拟合的行为,完成相应的交集以及差操作[^4]。 假设我们有两个线性表 A 和 B,则按照定义可得如下关系: - \( \text{A ∪ B} = (\text{仅属于 A 的部分}) + (\text{共同的部分}) + (\text{仅属于 B 的部分})\)[^4] - \( \text{A ∩ B} = (\text{同时存在于 A 和 B 的部分})\) 具体实现过程见下述伪码转换后的实际例子: ```c++ // 定义辅助函数用于判断某个数是否已经存在目标中 bool contains(int target[], int size, int value) { for(int k=0;k<size;++k){ if(target[k]==value)return true; } return false; } void compute_operations(const vector<int>& a, const vector<int>& b, vector<int>& union_result, vector<int>& intersect_result) { // 初始化结果容器大小足够容纳最大可能数量的结果项 int max_size = a.size()+b.size(); union_result.reserve(max_size); intersect_result.reserve(min((size_t)a.size(), b.size())); bool found_common=false; for(auto elem:a){ if(!contains(union_result.data(), union_result.size(),elem)){ union_result.push_back(elem); } if(std::find(b.begin(),b.end(),elem)!=b.end()){ intersect_result.push_back(elem); found_common=true; } } // 添加来自第二个合的独特成员至联合体里去 for(auto elem:b){ if(!contains(union_result.data(), union_result.size(),elem)) union_result.push_back(elem); } } ``` #### 总结 上述展示了多种编程语言和技术栈下的合运算处理办法,无论是高级抽象还是低级控制都有相应工具支持高效达成目的。每种方案各有优劣,在选用前需考虑性能需求、开发效率等因素综合评估最佳实践路径。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值