【database】oracle关联查询主表对应的特定一行从表结果集
主表:
从表:
结果集: 查询从表中年龄最大的一行数据,如果存在年龄相等的则为了保证唯一取id(主键)最大的一行。
一、利用sql子查询嵌套
-- --------------------------------
-- 利用sql子查询嵌套
-- --------------------------------
-- step 1. 子查询:找到每组最大的子类年龄
select parent_id,max(child_age) from child group by parent_id; -- step 2. 找到符合的行 (很可能出现重复)
select cc.* from child cc
INNER JOIN (select parent_id,max(child_age) child_age from child group by parent_id) tmp
on tmp.parent_id = cc.parent_id and tmp.child_age = cc.child_age
order by cc.parent_id,cc.child_id; -- step 3. 为了解决重复需要再加一层,取唯一标识id最大/最小的一行
select max(cc.child_id) from child cc
INNER JOIN (select parent_id,max(child_age) child_age from child group by parent_id) tmp
on tmp.parent_id = cc.parent_id and tmp.child_age = cc.child_age
group by cc.parent_id,cc.child_age -- step 4. 在3中就找到了符合条件行的id
select * from parent pa
LEFT JOIN (SELECT cc.* from child cc
INNER JOIN (select max(cc.child_id) child_id from child cc
INNER JOIN (select parent_id,max(child_age) child_age from child group by parent_id) tmp
on tmp.parent_id = cc.parent_id and tmp.child_age = cc.child_age
group by cc.parent_id,cc.child_age) tmp on TMP.child_id = cc.child_id
) tmp on tmp.parent_id = pa.parent_id
where 1=1 ORDER BY pa.parent_id;
二、利用oracle自带的分析函数
-- --------------------------------
-- 利用oracle分析函数
-- --------------------------------
-- step-1:找到子类符合的id, DISTINCT去重
select DISTINCT first_value(cc.child_id)
over(partition by cc.parent_id order by cc.parent_id,cc.child_age desc,cc.child_id desc) child_id
from child cc;
-- step-2: 符合的子类结果集
SELECT * from child cc where cc.child_id in(
select DISTINCT first_value(cc.child_id)
over(partition by cc.parent_id order by cc.parent_id,cc.child_age desc,cc.child_id desc) child_id
from child cc
); SELECT * from child cc where EXISTS ( select 1 from (
select DISTINCT first_value(cc.child_id)
over(partition by cc.parent_id order by cc.parent_id,cc.child_age desc,cc.child_id desc) child_id
from child cc) tmp where tmp.child_id = cc.child_id
); -- step-3: 最终结果集
select * from parent pa
LEFT JOIN child cc on cc.parent_id = pa.parent_id
and cc.child_id in(
select DISTINCT first_value(cc.child_id)over(partition by cc.parent_id order by cc.parent_id,cc.child_age desc,cc.child_id desc)
from child cc)
where 1=1 ORDER BY pa.parent_id
三、分析区别
sql嵌套当然要更通用点,而且看执行计划,它的效率、消耗都要比oracle少很多;
oracle分析函数感觉还是子查询嵌套了一层,而且效率、消耗都比较高。
(才知道oracle的执行计划,完全不懂。只是看着sql嵌套查询的执行计划高效很多)
四、测试数据
-- -----------------------------
-- PARENT 父表
-- -----------------------------
CREATE TABLE "PARENT" (
"PARENT_ID" NUMBER NOT NULL ,
"PARENT_NAME" VARCHAR2(255 BYTE) NOT NULL
)
LOGGING NOCOMPRESS NOCACHE;
-- Records of PARENT
INSERT INTO "PARENT" VALUES ('', '周父');
INSERT INTO "PARENT" VALUES ('', '吴父');
INSERT INTO "PARENT" VALUES ('', '郑父');
INSERT INTO "PARENT" VALUES ('', '王父');
INSERT INTO "PARENT" VALUES ('', '赵父');
-- Checks structure for table PARENT
ALTER TABLE "PARENT" ADD CHECK ("PARENT_ID" IS NOT NULL);
ALTER TABLE "PARENT" ADD CHECK ("PARENT_NAME" IS NOT NULL); -- -----------------------------
-- PARENT 子表
-- -----------------------------
CREATE TABLE "CHILD" (
"CHILD_ID" NUMBER NOT NULL ,
"CHILD_NAME" VARCHAR2(255 BYTE) NOT NULL ,
"CHILD_AGE" NUMBER NOT NULL ,
"PARENT_ID" VARCHAR2(255 BYTE) NOT NULL
)
LOGGING NOCOMPRESS NOCACHE; -- ----------------------------
-- Records of CHILD
-- ----------------------------
INSERT INTO "CHILD" VALUES ('', '周一', '', '');
INSERT INTO "CHILD" VALUES ('', '周二', '', '');
INSERT INTO "CHILD" VALUES ('', '周三', '', ''); INSERT INTO "CHILD" VALUES ('', '吴一', '', '');
INSERT INTO "CHILD" VALUES ('', '吴二', '', '');
INSERT INTO "CHILD" VALUES ('', '吴三', '', '');
INSERT INTO "CHILD" VALUES ('', '吴四', '', ''); INSERT INTO "CHILD" VALUES ('', '郑一', '', '');
INSERT INTO "CHILD" VALUES ('', '郑二', '', ''); INSERT INTO "CHILD" VALUES ('', '王一', '', ''); -- Checks structure for table CHILD
ALTER TABLE "CHILD" ADD CHECK ("CHILD_ID" IS NOT NULL);
ALTER TABLE "CHILD" ADD CHECK ("CHILD_NAME" IS NOT NULL);
ALTER TABLE "CHILD" ADD CHECK ("CHILD_AGE" IS NOT NULL);
ALTER TABLE "CHILD" ADD CHECK ("PARENT_ID" IS NOT NULL);
测试表结构和数据
【database】oracle关联查询主表对应的特定一行从表结果集的更多相关文章
- Oracle关联查询-数据类型不一致问题 ORA-01722: 无效数字
一.存在表A和表B,都包含字段user_no,但数据类型不一致,如下: create table A ( user_id varchar2(20), user_no number(12,0), xxx ...
- Oracle关联查询关于left/right join的那点事
/*题外话 --更改foreign key约束定义引用行(delete cascade/delete set null/delete no action),默认delete on action--引用 ...
- Oracle 关联查询
select count(1),a.policy_id from gp_pol_prod a where a.product_id=8401 group by a.policy_id having c ...
- oracle中查询、禁用、启用、删除表外键
1.查询所有表的外键的: select table_name, constraint_name from user_constraints where constraint_type = 'R'; ...
- SQL语句关联查询
一:连接类型: 关联查询:只有存在关联的表才能关联查询,完全独立的表之间无法关联 1.关联的类型:自关联,左关联,右关联,全关联(full join)两张表都是主表 2.关联的表:两张以上,以一张(或 ...
- mybatis collection 一对多关联查询,单边分页的问题总结!
若想直接通过sql实现多级关联查询表结构得有2 个必不可少的字段:id ,parentId,levelId id:主键id, parentId:父id levelId:表示第几级(表本身关联查询的时候 ...
- mysql如何执行关联查询与优化
mysql如何执行关联查询与优化 一.前言 在数据库中执行查询(select)在我们工作中是非常常见的,工作中离不开CRUD,在执行查询(select)时,多表关联也非常常见,我们用的也比较多,那么m ...
- mybatis实战教程二:多对一关联查询(一对多)
多对一关联查询 一.数据库关系.article表和user表示多对一的关系 CREATE TABLE `article` ( `id` ) NOT NULL AUTO_INCREMENT, `user ...
- 【SQL】在SQL Server中多表关联查询问题
好久没有写SQL语句的多表连接查询,总在用框架进行持久化操作.今天写了一个多表关联查询,想根据两个字段唯一确定一条数据 失败的案例如下: SELECT cyb.id,ad.name FROM [Gen ...
随机推荐
- springboot结合Docker部署
工程目录 创建Dockerfile FROM java VOLUME /tmp ADD springboot-docker-0.0.1-SNAPSHOT.jar app.jar RUN bash -c ...
- 【题解】P1020 导弹拦截
[题解]P1020 导弹拦截 从n^2到nlogn 第二问就是贪心,不多说 第一问: 简化题意:求最长不下降子序列 普通n^2: for (int i = 1; i <= n; i++) for ...
- c++ 初始化列表和构造函数初始化区别
先上代码 #include <iostream> class MyContruct { public: MyContruct() { std::cout << "My ...
- postman之批量数据参数化(文件)
相信小伙伴们在做接口测试时需要导入大量的数据进行测试,Jmeter进行接口测试时可以导入CSV数据文件进行参数化,那么postman又该如何导入数据文件进行测试呢?下面我给大家讲解一下. 第一:创建t ...
- 5年从DBA到运维架构总监 — 做对了什么
本文来自宝宝树运维总监刘秋岐的分享.随着MySQL的不断成熟,逐渐被用于更多大规模的网站和应用了,比如说当前最火的Facebook.淘宝.阿里.兰亭集势.宝宝树这样的大型的网站都在使用MySQL数据库 ...
- Sklearn--(SVR)Regression学习笔记
今天介绍一个机器学习包,sklearn.其功能模块有regression\classification\clustering\Dimensionality reduction\data preproc ...
- 将win10激活为专业工作站版并且永久激活(图文详细教程)
简介 win10升级为专业版.教育版.专业工作站版永久激活详细图文教程(注:只要使用相对应的产品密钥,所有的版本都可以激活) win10家庭版其实就是阉割版,越来越多的人想升级为专业版.很多电脑用户选 ...
- Mysql 5.7 主从复制的多线程复制配置方式
数据库复制的主要性能问题就是数据延时 为了优化复制性能,Mysql 5.6 引入了 “多线程复制” 这个新功能 但 5.6 中的每个线程只能处理一个数据库,所以如果只有一个数据库,或者绝大多数写操作都 ...
- 【5min+】 设计模式的迷惑?Provider vs Factory
系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...
- 赛狗日源码分享 《Head First C#》第三版
目录 前言 效果展示 步骤 熟读任务说明 搭界面 开始代码 From.cs Greyhound.cs Guy.cs Bet.cs 写在后面的话 本次遇见的一些问题 关于优化 可以设定狗的特性 去掉Be ...