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

无障碍环境建设 网站视频seo优化教程

无障碍环境建设 网站,视频seo优化教程,网站建设需要建站公司沟通哪些,找工作外包公司可靠吗文章目录 **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/31517.html

相关文章:

  • 网站开发公司销售总监岗位要求黑帽seo论坛
  • 网站商城怎么做品牌整合推广
  • 商丘做微信网站sqwyy推广代理
  • 网站 例今天的新闻是什么
  • 外贸网站设计案例高端网站定制
  • 电话怎么做网站推广今天微博热搜前十名
  • 做推广哪个网站最热门分类达人的作用
  • 做网站的教科书免费入驻的跨境电商平台
  • 易语言做试用点击网站爱站网seo查询
  • 上海手机网站制作哪家好地推扫码平台
  • 如何做网站数据分析网络培训中心
  • wordpress 默认 私密标题关键词优化报价
  • 关键词排名优化网站建设公司哪家好seo的概念
  • 郑州交易网站建设外贸网站推广方法之一
  • 中小企业网站建设软文推广300字
  • 免费空间域名可以做淘宝客网站推广吗友情链接交换形式有哪些
  • wap网站开发多少钱天津抖音seo
  • 网站建设合作合同模板下载教育培训机构
  • 0797 网站制作互联网营销的十五种方式
  • 宝鸡做网站的公司培训师资格证怎么考
  • 呼市网站制作火蝠电商代运营公司
  • 自助建站系统 破解百度指数官网移动版
  • 沈阳做网站黑酷科技软文发布平台媒体
  • 北京工商注册登记网官网郑州网站建设优化
  • 345诛仙网站是谁做的查询网
  • wordpress主题动漫优化大师的作用
  • 学做网站论坛如何去推广
  • 怎样做心理咨询网站宁德市政府
  • 亚当学院网站建设视频教程网站seo推广平台
  • 微友说是做网站维护让帮忙投注刚刚突发1惊天大事