当前位置: 首页 > wzjs >正文

有寓意的logo设计图片安徽网络seo

有寓意的logo设计图片,安徽网络seo,成品软件网站大全推荐,wordpress小程序课程文章目录 **0.实际场景:查询每个 rs 值对应的最新记录****场景描述****表结构示例**公司业务中实际场景改造前:改造后:改造后的纯SQL **1. 什么是子查询?****2. 子查询的分类****(1) 按结果类型分类****(2) 按执行位置分类** **3.…

在这里插入图片描述

文章目录

    • **0.实际场景:查询每个 `rs` 值对应的最新记录**
      • **场景描述**
      • **表结构示例**
      • 公司业务中实际场景
        • 改造前:
        • 改造后:
        • 改造后的纯SQL
    • **1. 什么是子查询?**
    • **2. 子查询的分类**
      • **(1) 按结果类型分类**
      • **(2) 按执行位置分类**
    • **3. 子查询的实际应用**
      • **(1) 在 `WHERE` 子句中使用子查询**
        • **示例:查找工资高于公司平均工资的员工**
      • **(2) 在 `SELECT` 语句中使用子查询**
        • **示例:为每位员工显示其所在部门的平均工资**
      • **(3) 在 `FROM` 子句中使用子查询(派生表)**
        • **示例:查询每个部门工资最高的员工**
      • **(4) 使用 `EXISTS` 进行数据检查**
        • **示例:查询至少有一名员工的部门**
      • **(5) 结合 `UPDATE` 或 `DELETE` 语句**
        • **示例:将工资低于部门平均工资的员工加薪 10%**
        • **示例:删除未分配员工的部门**
    • **4. 子查询 vs `JOIN` 性能对比**
      • **子查询的性能劣势**
      • **`JOIN` 的优势**
      • **结论**
    • **5. 子查询优化技巧**
    • **6. 结论**

在 MySQL 开发过程中,我们经常需要从同一张表中获取特定条件下的最新记录或进行去重查询。

这种场景下,子查询(Subquery) 是一种常用且强大的 SQL 技术。本文将通过一个实际案例,介绍子查询的概念、应用及优化方式。

0.实际场景:查询每个 rs 值对应的最新记录

场景描述

假设有一个 hd_com_locinfo 表,存储了一些位置信息,每个 rs 可能有多条记录,但 times 字段表示数据的时间,我们希望rs 进行去重,并保留 times 最新的那一条数据

表结构示例

CREATE TABLE `hd_com_locinfo` (`locid` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID,自增,chr+start+end+type可唯一确定一个rsid',`rs` varchar(15) DEFAULT NULL COMMENT 'rs号,位点信息表',`chr` char(5) NOT NULL COMMENT '染色体',`start` int(11) NOT NULL COMMENT '起始位置',`end` int(11) NOT NULL COMMENT '结束位置',`type` varchar(30) NOT NULL COMMENT '突变类型,插入缺失dbsnp',`ref` varchar(200) DEFAULT NULL COMMENT '参考基因,有时可能很长',`gene_name` varchar(100) DEFAULT NULL COMMENT '基因名称',`cchange` varchar(100) DEFAULT NULL COMMENT 'c.变化',`pchange` varchar(100) DEFAULT NULL COMMENT 'p.变化',`alt` varchar(200) DEFAULT NULL COMMENT '等位基因,多个使用英文逗号,分割',`gchange` varchar(100) DEFAULT NULL COMMENT 'g.变化,主要是药物使用',`frequency` varchar(15) DEFAULT NULL,`gene_region` varchar(150) DEFAULT NULL COMMENT '基因区域',`times` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`isshow` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否启用该项,0:关闭,1:开启',PRIMARY KEY (`locid`) USING BTREE,KEY `rs` (`rs`) USING BTREE,KEY `start` (`start`) USING BTREE,KEY `end` (`end`) USING BTREE,KEY `type` (`type`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='位点信息表';

公司业务中实际场景

在小程序开发中,针对基因报告数据中,位点信息当两条就差一个一字段就相同的sql语句,现在业务场景需要只能保留最新的一条数据。如下图:
在这里插入图片描述

改造前:

Go中gorm的操作

func (g *Gabd3Dao) FindLikeLocinfoByRs(rs string) (result []map[string]any, err error) {var hdLocinfo []model.HdComLocinfoif err := g.Gabd3.Where("rs LIKE ?", rs+"%").Find(&hdLocinfo).Order("times desc").Group("rs").Error; err != nil {return []map[string]any{}, err}for _, v := range hdLocinfo {result = append(result, tools.JSONMethod(v))}return result, nil
}
改造后:

func (g *Gabd3Dao) FindLikeLocinfoByRs(rs string) (result []map[string]any, err error) {var hdLocinfo []model.HdComLocinfo// 使用子查询保留时间最新的记录subQuery := g.Gabd3.Model(&model.HdComLocinfo{}).Select("MAX(times) as latest_time, rs").Where("rs LIKE ?", rs+"%").Group("rs")if err := g.Gabd3.Table("hd_com_locinfo h").Select("h.*").Joins("JOIN (?) sub ON h.rs = sub.rs AND h.times = sub.latest_time", subQuery).Find(&hdLocinfo).Error; err != nil {return nil, err}// 转换结果for _, v := range hdLocinfo {result = append(result, tools.JSONMethod(v))}return result, nil
}或者是:func (g *Gabd3Dao) FindLikeLocinfoByRs(rs string) (result []map[string]any, err error) {var hdLocinfo []model.HdComLocinfoquery := `SELECT h.* FROM hd_com_locinfo hJOIN (SELECT rs, MAX(times) AS latest_time FROM hd_com_locinfo WHERE rs LIKE ? GROUP BY rs) sub ON h.rs = sub.rs AND h.times = sub.latest_time`if err := g.Gabd3.Raw(query, rs+"%").Scan(&hdLocinfo).Error; err != nil {return nil, err}// 转换结果for _, v := range hdLocinfo {result = append(result, tools.JSONMethod(v))}return result, nil
}
改造后的纯SQL

使用 MAX(times) 计算每个 rs 最新的 times,然后用 JOIN 筛选出对应的完整记录:

SELECT h.*
FROM hd_com_locinfo h
JOIN (SELECT rs, MAX(times) AS latest_timeFROM hd_com_locinfoWHERE rs LIKE "rs716274%"GROUP BY rs
) sub ON h.rs = sub.rs AND h.times = sub.latest_time;

1. 什么是子查询?

子查询(Subquery) 是指嵌套在另一个 SQL 语句中的查询,它的执行结果可以作为主查询的输入。子查询可以用于 SELECTINSERTUPDATEDELETE 语句中,通常用于筛选数据、计算聚合值、去重等场景。

子查询的主要作用:

  1. 数据筛选(在 WHEREHAVING 子句中使用)
  2. 计算某些字段的聚合值(如 MAX()AVG()
  3. EXISTS 结合,用于检查数据是否存在
  4. 用作派生表(Derived Table),作为 FROM 子句的临时表
  5. 用于数据更新和删除

2. 子查询的分类

MySQL 中的子查询可以按照不同的执行方式分类:

(1) 按结果类型分类

  1. 标量子查询(Scalar Subquery):返回单个值
  2. 行子查询(Row Subquery):返回一行数据
  3. 表子查询(Table Subquery):返回多行多列数据

(2) 按执行位置分类

  1. WHERE 子查询:用于筛选数据
  2. SELECT 子查询:用于计算某个字段的值
  3. FROM 子查询(派生表):作为临时表供主查询使用
  4. EXISTS 子查询:用于判断是否存在匹配数据

3. 子查询的实际应用

(1) 在 WHERE 子句中使用子查询

用于筛选符合特定条件的数据。

示例:查找工资高于公司平均工资的员工
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
  • 子查询 SELECT AVG(salary) FROM employees 计算公司平均工资
  • 主查询 WHERE salary > 只保留工资高于平均值的员工

(2) 在 SELECT 语句中使用子查询

子查询可以作为 SELECT 的一部分,为每条记录计算某些值。

示例:为每位员工显示其所在部门的平均工资
SELECT name, salary, (SELECT AVG(salary) FROM employees e2 WHERE e2.department_id = e1.department_id) AS dept_avg_salary
FROM employees e1;
  • SELECT AVG(salary) ... 计算每个部门的平均工资
  • AS dept_avg_salary 让主查询展示这个计算值

(3) 在 FROM 子句中使用子查询(派生表)

子查询可以在 FROM 语句中作为一个临时表使用,称为“派生表”(Derived Table)。

示例:查询每个部门工资最高的员工
SELECT department_id, MAX(salary) AS max_salary
FROM employees
GROUP BY department_id;

我们可以用这个子查询作为临时表:

SELECT e.name, e.salary, max_salaries.department_id
FROM employees e
JOIN (SELECT department_id, MAX(salary) AS max_salaryFROM employeesGROUP BY department_id
) max_salaries
ON e.department_id = max_salaries.department_id AND e.salary = max_salaries.max_salary;
  • SELECT department_id, MAX(salary) 作为派生表
  • JOIN 让主查询匹配工资最高的员工

(4) 使用 EXISTS 进行数据检查

EXISTS 用于判断子查询是否返回数据,而不是具体的数据内容。

示例:查询至少有一名员工的部门
SELECT department_id, department_name
FROM departments d
WHERE EXISTS (SELECT 1 FROM employees e WHERE e.department_id = d.department_id
);
  • EXISTS 只关心子查询是否返回数据,提高查询效率

(5) 结合 UPDATEDELETE 语句

子查询可以用于更新或删除特定数据。

示例:将工资低于部门平均工资的员工加薪 10%
UPDATE employees e1
SET salary = salary * 1.1
WHERE salary < (SELECT AVG(salary) FROM employees e2 WHERE e1.department_id = e2.department_id);
  • 子查询 SELECT AVG(salary) ... 计算每个部门的平均工资
  • UPDATE 只更新工资低于平均值的员工
示例:删除未分配员工的部门
DELETE FROM departments
WHERE department_id NOT IN (SELECT DISTINCT department_id FROM employees);
  • 子查询 SELECT DISTINCT department_id FROM employees 获取所有已分配的部门
  • DELETE 删除未在员工表中的部门

4. 子查询 vs JOIN 性能对比

子查询有时比 JOIN 慢,以下是对比分析:

子查询的性能劣势

  1. 子查询可能执行多次

    SELECT * FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'New York');
    
    • 如果 departments 有 1000 行,每次主查询执行时,子查询可能执行 1000 次。
  2. 子查询无法使用索引优化

    • IN (SELECT ... FROM ...) 可能会导致全表扫描。

JOIN 的优势

  1. JOIN 只执行一次

    SELECT e.* 
    FROM employees e
    JOIN departments d ON e.department_id = d.department_id
    WHERE d.location = 'New York';
    
    • 通过 JOIN,MySQL 只执行一次表连接,提高效率。

结论

  • 当子查询返回大量数据时,建议使用 JOIN,减少查询次数,提高性能。
  • 如果子查询结果较小,并且仅用于存在性检查(EXISTS),子查询可能更高效。

5. 子查询优化技巧

1. 避免 IN,优先使用 JOIN

--  低效:
SELECT * FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'New York');--  推荐:
SELECT e.* FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE d.location = 'New York';

2. 使用 EXISTS 替代 IN

--  低效:
SELECT * FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'New York');--  更快:
SELECT * FROM employees e WHERE EXISTS (SELECT 1 FROM departments d WHERE e.department_id = d.department_id AND d.location = 'New York');

3. 添加适当的索引

  • 如果 times 频繁用于 MAX(),建议创建索引:

    CREATE INDEX idx_times ON employees(times);
    

6. 结论

  • 子查询是 MySQL 强大的查询工具,可用于数据筛选、计算、存在性检查等。

  • 在数据量较大时,子查询可能比 JOIN,应合理选择优化方案。

  • MySQL 8.0+ 提供了更强的优化机制,如 WITH RECURSIVE,可以进一步优化查询性能。

在实际项目中,结合 JOINEXISTS 和索引优化,可以提升 MySQL 查询性能!

http://www.dtcms.com/wzjs/7676.html

相关文章:

  • 南昌集团制作网站开发kol营销
  • wordpress 自建cdn南昌seo推广公司
  • 芜湖注册公司流程和费用衡水seo营销
  • 做直播网站需要什么南昌百度网站快速排名
  • 秀洲区建设局网站网址大全名称
  • 合肥网站建设的价格seo怎么做关键词排名
  • 网站设计摘要 优帮云今日新闻热点10条
  • 泰安网站建设策划方案win10最强优化软件
  • 苹果手机编程软件优化关键词的作用
  • 如何制作门户网站网址查询注册信息查询
  • 公司内网站建设seo标题优化是什么意思
  • 公众号开发 订阅号seo建站教程
  • 怎样查网站有没有做CDN加速seo公司网站推广
  • ppt怎么制作教程深圳有实力的seo公司
  • 制作重庆城市的网页网站seo查询
  • 什么是企业网站建设网页做推广
  • 怎么在阿里巴巴网站做公司名称2022百度搜索风云榜
  • 落实政府网站集约化建设工作怎么建设自己的网站
  • 建设学院网站的通知书seo推广系统排名榜
  • wordpress做视频网站吗青岛seo青岛黑八网络最强
  • 个人社区网站备案百度搜索排行榜风云榜
  • 网站后台 刷新厦门seo报价
  • 宠物网站建设方案百度有效点击软件
  • 中国半导体设备重庆seo培训
  • 微信公众号做微网站吗合肥seo外包平台
  • 铜陵公司做网站什么是seo营销
  • 做时时彩怎么做网站怎么样建立自己的网站
  • 做网站时背景图片浮动什么是seo搜索引擎优化
  • 如何给网站做dns解析谷歌seo搜索引擎
  • 本溪 网站建设 做网站西安竞价推广托管