首页 > 数据库 >【转】【SQL】 实现左单一匹配

【转】【SQL】 实现左单一匹配

时间:2024-07-02 09:10:42浏览次数:15  
标签:匹配 NAME TIMEKEY MONTH TAB SQL TEST 单一 SELECT

原文地址:https://blog.csdn.net/weixin_46156257/article/details/131234451

SQL的表连接中,如果主表中同一条数据对应被连接表有多条数据,则连接后数据会被扩大,但有时候我们希望数据不要被扩大,与主表中数据条数保持一致,即实现左单一匹配连接。

假设我们有学生信息表TEST_TAB_STUDENTS和学生成绩表TEST_TAB_SCORE,如下:

TEST_TAB_STUDENTS:

NAME STU_NUMBER CLASS GRADE
张三 23578 三班 五年级
李四 23632 二班 五年级
王五 23448 一班 六年级
赵六 32251 三班 四年级

TEST_TAB_SCORE:

 

如果需要将学生表中匹配出每个学生的任意一笔成绩(或按一定顺序一条),则需要用到左单一匹配。

先将被连接表排序后取一条(如果是任意一条则可以写order by 1)

SELECT A.NAME,A.STU_NUMBER,A.CLASS,A.GRADE,C.MONTH_TIMEKEY,C.CHINESE,C.MATHS,C.ENGLISH,C.PHYSICS,C.CHEMISTRY,C.BIOLOGY
FROM TEST_TAB_STUDENTS A
--如果需要按某一列排序,例如取时间最后的一条成绩,可改为ORDER BY MONTH_TIMEKEY DESC
LEFT JOIN (SELECT B.*,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY 1) RN FROM TEST_TAB_SCORE B) C
ON A.NAME = C.NAME 
WHERE C.RN = 1

 

输出:

 2. 通过hint:first_rows查找被连接表中按一定顺序后的第一条(或任意一条)

如果连接后只需查找一列,如语文成绩,则可直接查找:

 1 --根据MONTH_TIMEKEY排序取最后一条数据
 2 SELECT A.NAME,A.STU_NUMBER,A.CLASS,A.GRADE,
 3 (SELECT /*+ FIRST_ROWS*/CHINESE
 4     FROM
 5     (SELECT CHINESE 
 6     FROM TEST_TAB_SCORE B
 7     WHERE A.NAME = B.NAME
 8     ORDER BY MONTH_TIMEKEY DESC 
 9     ) WHERE ROWNUM<=1
10 ) AS CHINESE
11 FROM TEST_TAB_STUDENTS A
12  
13 --不需要排序取任意一条
14 SELECT A.NAME,A.STU_NUMBER,A.CLASS,A.GRADE,
15 (SELECT /*+ FIRST_ROWS*/CHINESE
16     FROM TEST_TAB_SCORE B
17     WHERE A.NAME = B.NAME
18     AND ROWNUM<=1
19 ) AS CHINESE
20 FROM TEST_TAB_STUDENTS A

如果连接后需要的列较多,如各科成绩都需要,则重复查找会耗费性能,可以先查找出ROWID,再左连接:

 1 --根据MONTH_TIMEKEY排序取最后一条数据
 2 SELECT AA.NAME,AA.STU_NUMBER,AA.CLASS,AA.GRADE,C.MONTH_TIMEKEY,C.CHINESE,C.MATHS,C.ENGLISH,C.PHYSICS,C.CHEMISTRY,C.BIOLOGY
 3 FROM (
 4     SELECT A.NAME,A.STU_NUMBER,A.CLASS,A.GRADE,
 5     (SELECT /*+ FIRST_ROWS*/ROW_ID
 6         FROM
 7         (SELECT ROWID ROW_ID 
 8         FROM TEST_TAB_SCORE B
 9         WHERE A.NAME = B.NAME
10         ORDER BY MONTH_TIMEKEY DESC
11         ) WHERE ROWNUM<=1
12     ) AS ROW_ID
13     FROM TEST_TAB_STUDENTS A
14 ) AA 
15 LEFT JOIN TEST_TAB_SCORE C ON AA.ROW_ID = C.ROWID
16  
17 --不需要排序取任意一条
18 SELECT AA.NAME,AA.STU_NUMBER,AA.CLASS,AA.GRADE,C.MONTH_TIMEKEY,C.CHINESE,C.MATHS,C.ENGLISH,C.PHYSICS,C.CHEMISTRY,C.BIOLOGY
19 FROM (
20     SELECT A.NAME,A.STU_NUMBER,A.CLASS,A.GRADE,
21     (SELECT /*+ FIRST_ROWS*/ ROWID ROW_ID 
22         FROM TEST_TAB_SCORE B
23         WHERE A.NAME = B.NAME
24         AND ROWNUM<=1
25     ) AS ROW_ID
26     FROM TEST_TAB_STUDENTS A
27 ) AA 
28 LEFT JOIN TEST_TAB_SCORE C ON AA.ROW_ID = C.ROWID

3. 两种方法比较

两种方式均能实现需求,在不同场景性能表现有所不同:

方法1采用排序后hash join的方式,适用于主表(TEST_TAB_STUDENTS)较大,而被匹配表(TEST_TAB_SCORE)较小的情况,因为被匹配表需要全部排序;方法2则采用first_row方式迭代取出B表的第一条数据,适用于主表(取出的数据)较小,而B表较大的情况。

 

标签:匹配,NAME,TIMEKEY,MONTH,TAB,SQL,TEST,单一,SELECT
From: https://www.cnblogs.com/luyj00436/p/18279237

相关文章

  • 基于web的酒店客房管理系统 毕业设计 springboot+Vue+mysql
    介绍我开发了一个基于Web的酒店客房管理系统,旨在通过现代化的管理工具提升酒店客房管理的效率和用户体验。该系统分为管理员角色和用户角色,管理员负责管理用户、客房信息、预约、入住、退房等内容,用户则可以查询客房信息、进行预约、管理入住和退房等操作。系统通过丰富的功能......
  • Python毕业设计-基于Python实现的深圳链家租房可视化系统源码+文档说明+条形图+数据库
    文章目录源码下载地址项目介绍项目功能界面预览项目备注源码下载地址源码下载地址点击这里下载代码项目介绍项目历经数据采集->数据展示->数据分析->数据预测lianjia_1:scrapy爬虫项目lianjia_show:flask对采集的数据进行展示链家房价预测:采集的数据进行分析......
  • mysql基础语句实列
    --增insertintobooks(book_name)VALUES('盗墓笔记')insertintochapters(chapter_name,book_id)VALUES('盗墓笔记第三章',1)--查selectidfrombooksselect*fromchaptersselectid,chapter_namefromchapters--两表联查selectbooks.id,book_name,cha......
  • 突破SQL基本面试问题(0)
    写作原因:在当今数据驱动的商业环境中,SQL作为数据分析师的核心工具,其重要性日益凸显。它不仅是查询和操作数据库的语言,更是连接数据与洞察力的桥梁。随着大数据技术的飞速发展,众多顶级企业,包括华为等大厂,已经将SQL基础能力的考察纳入到面试流程中,作为评估候选人是否具备高效......
  • mysql数据库基本语句
    –查看所有数据库。showdatabases;–切换到指定数据库。usemysql;-查看数据库下所有表showtables;–其常用他命令。查看当前用户:selectuser();当前日期时间selectnow();查看数据库状态:\s;退出数据库:\q;基本操作:创建库、创建表、删除库、删除表、修改库、修改表......
  • 一款利用人工智能将自然语言查询转换为 SQL 代码的互译工具 - SQL Translator
    https://www.sqltranslate.app/ 一款利用人工智能将自然语言查询转换为SQL代码的互译工具-SQLTranslator 思维导航前言SQLTranslator介绍工具特性本地项目部署在线效果演示程序员常用的工具软件前言对于后端程序员来说,编写SQL代码是日常工作中不可或缺......
  • 数据库系列-mysql-sql执行示例
    数据库定义语言--数据库查询语句模板--!数据库创建--创建数据库test,如果存在则不创建,默认字符集为utf8,不区分大小写,cs为大小写敏感,也可以使用utf8_bin,字符采用二进制存储CREATEDATABASEIFNOTEXISTS`test`DEFAULTCHARACTERSETutf8COLLATEutf8_general_ci;......
  • sql-server创建存储过程
    useEFDBgo--添加学生存储过程--usp_AddStudents自定义的存储过程nameifexists(select*fromsysobjectswherename='usp_AddStudents')dropprocedureusp_AddStudentsgo--@StudentNamevarchar(20),对应表中的字段--@Genderchar(2),对应表中的字段--@Birthday......
  • Spark_04 SparkSQL的介绍及使用
    说明这一章主要包括对于sparksql概念的介绍,sparksql的特点,sparksql用到的数据类型,DataFrame的基础方法等。概念SparkSQL是Spark用于处理结构化数据的模块。诞生由于MapReduce这种计算模型的执行效率较慢,rdd原生代码较为复杂,所以引入了SparkSQL应运而生。它可以将sql转换为......
  • MySQL—创建和修改数据表结构
    创建表实例:CREATETABLE`user`(idINT,`name`VARCHAR(255),`password`VARCHAR(255),`birthday`DATE)CHARACTERSETutf8COLLATEutf8_binENGINEINNODB;显示数据库中的表showtablesfromhsp;显示表结构descdept;修改......