还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
基础语句教程SQL欢迎参加基础SQL语句教程!在这个全面的课程中,我们将从零开始学习SQL(结构化查询语言),帮助您掌握数据库操作的基本技能无论您是完全的初学者还是希望巩固基础知识,本课程都将提供清晰的概念解释和实用的示例什么是?SQL结构化查询语言发展历程与标准SQL(Structured QueryLanguage,结构化查询语言)是SQL起源于20世纪70年代IBM的System R项目,最初被称一种专门用于管理关系型数据库的标准编程语言它允许为SEQUEL1986年,美国国家标准协会(ANSI)发布了用户创建、修改、查询和管理数据库中的数据,是与数据第一个SQL标准,随后国际标准化组织(ISO)也采纳了这库交互的主要方式一标准SQL语言简单易学,具有强大的功能,能够处理大量数据并提供高效的数据操作方法即使没有编程经验的人也能较快地掌握基本用法常见应用场景SQL数据库管理SQL是数据库管理员(DBA)的核心工具,用于创建和维护数据库结构、管理用户权限、监控数据库性能以及执行备份和恢复操作通过SQL语句,DBA可以轻松地调整数据库参数,确保数据库系统的高效运行和数据安全数据查询与分析数据分析师和业务用户使用SQL从数据库中提取有价值的信息,支持商业决策SQL强大的聚合和筛选功能使其成为数据挖掘和商业智能的理想工具从简单的销售报表到复杂的用户行为分析,SQL都能够轻松应对程序开发对接主流数据库介绍MySQL作为全球最流行的开源关系型数据库之一,MySQL以其高性能、可靠性和易用性而闻名它是LAMP(Linux+Apache+MySQL+PHP)架构的重要组成部分,广泛应用于网站和网络应用现在归Oracle公司所有,但仍保持开源版本Oracle DatabaseOracle数据库是市场领先的企业级关系型数据库系统,以其强大的事务处理能力、高可用性和安全性著称它提供全面的数据管理解决方案,广泛应用于大型企业和政府机构,尤其是在金融、电信和制造业领域SQL Server微软开发的SQL Server提供全面的数据平台解决方案,与Windows系统和.NET框架深度集成它具有强大的商业智能工具、高性能分析服务和报表功能,在使用微软技术栈的企业中普遍采用PostgreSQLPostgreSQL是一个功能强大的开源对象关系型数据库系统,以其可靠性、数据完整性和正确性而著称它支持先进的数据类型和性能优化,拥有活跃的开发社区,在需要复杂查询和大数据量处理的应用中表现出色语言结构概览SQL数据定义语言()DDL用于定义数据库结构数据操纵语言()DML用于管理数据库中的数据数据控制语言()DCL用于控制访问权限事务控制语言()TCL用于管理事务处理SQL语言从功能上可以分为四大类DDL主要包括CREATE、ALTER、DROP等用于创建和修改数据库对象的命令;DML包括SELECT、INSERT、UPDATE、DELETE等用于数据操作的命令;DCL包括GRANT、REVOKE等权限管理命令;TCL包括COMMIT、ROLLBACK等事务管理命令SQL语句的基本结构通常包含关键字、标识符、表达式和运算符等元素每条SQL语句都以分号结尾,并且可以跨多行编写以提高可读性虽然不同数据库系统可能有细微差异,但基本语法结构是一致的数据库与表的概念数据库()表()Database Table数据库是相关数据的有组织集合,表是数据库中存储数据的基本单它存储、管理和处理数据可以将位,由行和列组成每个表代表一数据库想象为一个电子文件柜,用个实体类型(如客户、产品或订于存储结构化信息在实际应用单),包含该实体的多个实例例中,一个公司可能有多个数据库,如,客户表中的每一行代表一个如人力资源数据库、财务数据库和客户,而列则代表客户的属性,如客户关系数据库等姓名、地址和电话号码记录与字段记录(也称为行或元组)是表中的一个数据项,代表一个实体的实例字段(也称为列或属性)定义了记录中存储的特定类型的数据例如,在学生表中,一条记录包含单个学生的所有信息,而学号、姓名和年龄等是不同的字段语句的标准书写规则SQL大小写约定注释语法SQLSQL关键字和函数名不区分大小写,例如SELECT、select和Select被视为相SQL支持两种注释风格单行注释使用两个连字符(--)开始,一直延续到同然而,为了提高代码可读性,通常建议将所有SQL关键字大写,将表名该行结束;多行注释使用/**/包围,可以跨越多行注释是记录SQL代码的和列名采用一致的大小写格式重要方式,有助于提高代码的可维护性需要注意的是,在某些数据库系统(如MySQL在特定设置下)中,表名和数示例据库名可能区分大小写,特别是在Unix/Linux系统中因此,最佳实践是始终以相同的方式引用表名和列名--这是单行注释SELECT*FROM employees;--查询所有员工/*这是多行注释,可以跨越多行*/SELECTemployee_id,first_nameFROM employees;数据类型基础数值型字符型•INTEGER/INT整数•CHAR固定长度字符串•SMALLINT小范围整数•VARCHAR可变长度字符串•DECIMAL/NUMERIC精确小数•TEXT长文本数据•FLOAT/REAL浮点数其他数据类型日期时间型•BOOLEAN逻辑值真/假•DATE日期年月日•BLOB二进制大对象•TIME时间时分秒•JSON结构化数据特定数据库•TIMESTAMP日期和时间创建数据库基本语法创建数据库使用CREATE DATABASE语句,其基本语法非常简单在大多数数据库系统中,只需要指定数据库名称即可创建一个新的数据库例如CREATE DATABASEschool;这条语句创建了一个名为school的新数据库在执行此命令之前,必须确保当前用户有创建数据库的权限带属性的创建在创建数据库时,可以指定各种属性,如字符集、排序规则等不同的数据库系统支持不同的属性设置例如,在MySQL中设置字符集和排序规则CREATE DATABASEschoolCHARACTER SETutf8mb4COLLATE utf8mb4_unicode_ci;这将创建一个使用UTF-8编码并支持多种语言的数据库,并指定了Unicode排序规则条件创建为了避免重复创建数据库导致错误,可以使用条件语句在MySQL中,可以使用IF NOTEXISTS子句CREATE DATABASEIF NOTEXISTS school;这条语句会先检查名为school的数据库是否已存在如果不存在,则创建它;如果已存在,则不执行任何操作,也不会报错这在脚本和自动化部署中特别有用删除与切换数据库删除数据库使用DROP DATABASE语句可以完全删除一个数据库及其所有内容,包括表、索引、视图等所有对象基本语法为DROP DATABASEschool;删除操作是永久性的且无法撤销,因此在执行此命令之前应当备份重要数据为避免数据库不存在时报错,可以使用条件语句DROP DATABASEIF EXISTSschool;切换当前数据库在执行数据库操作前,通常需要先选择要使用的数据库在MySQL、MariaDB等系统中,使用USE语句USE school;在SQL Server中,可以使用类似语法或显式写全限定名称USE school;--或使用完全限定名SELECT*FROM school.dbo.students;查看数据库列表不同数据库系统提供了不同的命令来查看可用的数据库列表•MySQL/MariaDB:SHOW DATABASES;•SQL Server:SELECT nameFROM sys.databases;•PostgreSQL:\l在psql客户端中•Oracle:SELECT*FROM v$database;查看当前数据库创建表语法字段定义CREATE TABLE创建表是构建数据库结构的基本操作表由字段(列)组每个字段定义包括字段名、数据类型和可选的约束字段名成,每个字段有特定的数据类型和约束基本的CREATE应该清晰地表示其存储的数据,并且遵循命名规则(通常不TABLE语法包括表名、字段名、数据类型和可选的约束条能以数字开头,不含特殊字符等)件数据类型必须适合存储的数据例如,使用INT存储整数,VARCHAR存储可变长度文本,DATE存储日期等选择合适CREATE TABLEstudents的数据类型可以优化存储空间和查询性能student_id INTPRIMARY KEY,name VARCHAR50NOT NULL,约束用于确保数据的完整性,如PRIMARY KEY(主键)确保age INT,每条记录唯一,NOT NULL确保字段不能为空等grade DECIMAL3,1,enrollment_date DATE;字段约束类型主键非空唯一PRIMARY KEYNOT NULLUNIQUE主键约束用于唯一标识表中的每一行,不NOT NULL约束要求列必须包含值,不允UNIQUE约束确保列中的所有值都是唯一的,允许重复值或NULL值通常用于表示实许NULL值这用于确保重要数据不会缺不允许重复值,但可以包含NULL值(除体的唯一标识符,如学生ID、员工编号等失,例如用户的姓名或产品的价格非同时设置了NOT NULL)适用于需要一个表只能有一个主键,但主键可以由多NULL表示未知或不适用的值,与空字符唯一但不作为主键的字段,如电子邮件地个列组成(复合主键)串或零不同址或身份证号码student_id INTPRIMARY KEYname VARCHAR50NOT NULLemail VARCHAR100UNIQUE外键FOREIGN KEY外键约束建立表之间的关系,确保引用的值在被引用表的对应列中存在它维护了数据的参照完整性,防止创建孤立的记录例如,订单表的客户ID必须存在于客户表中department_id INT,FOREIGN KEYdepartment_idREFERENCES departmentsid修改表结构添加新字段1使用ALTER TABLE语句和ADD子句可以向现有表添加新列可以同时指定数据类型和约束条件ALTER TABLEstudentsADD emailVARCHAR100UNIQUE;添加多个列时,可以在一条语句中完成ALTER TABLEstudentsADD phoneVARCHAR20,ADD addressVARCHAR200;修改现有字段2使用MODIFY(MySQL/Oracle)或ALTER COLUMN(SQL Server)可以更改字段的数据类型、长度或约束--MySQL语法ALTER TABLEstudentsMODIFY name VARCHAR100NOT NULL;--SQL Server语法ALTER TABLEstudentsALTER COLUMNnameVARCHAR100NOT NULL;删除字段3使用DROP COLUMN子句可以从表中删除不再需要的列ALTER TABLEstudentsDROP COLUMNaddress;删除操作会永久移除字段及其所有数据,无法恢复,因此执行前应谨慎考虑重命名字段或表4不同数据库系统提供了不同的重命名语法删除表语法与对比DROP TABLETRUNCATE DELETEDROP TABLE命令用于从数据库中完全删除表结构和所有数据一旦执如果只想删除表中的数据而保留表结构,可以使用TRUNCATE TABLE或行,表的所有信息(包括结构、数据、索引、约束等)都将永久丢失DELETE命令基本语法为TRUNCATE TABLE快速删除表中所有数据,不可回滚,不触发触发器,重置自增计数器DROP TABLEstudents;TRUNCATE TABLEstudents;为避免在表不存在时报错,可以使用条件语句DELETE FROM可以有条件地删除数据,操作可以回滚,会触发触发DROP TABLEIF EXISTSstudents;器,保留自增计数器当前值如果表有外键约束关联,可能需要先删除这些约束或使用CASCADE选DELETE FROM students;--删除所有行项(如果数据库支持)DELETE FROM students WHERE grade60;--条件删除DROPTABLEstudents CASCADE;一般来说,TRUNCATE比DELETE更高效,特别是对大表,但DELETE提供更多的灵活性和安全性查询基础SELECT基本语句SELECTSELECT语句是SQL中最常用的命令,用于从数据库检索数据最基本的SELECT语句包含两个主要子句SELECT(指定要检索的列)和FROM(指定数据来源的表)SELECT column1,column2,...FROM table_name;查询所有列使用星号(*)可以选择表中的所有列这在探索数据或需要表的完整信息时很有用,但在生产环境中,最好明确指定需要的列以提高性能SELECT*FROM students;查询指定列通常,为了提高查询效率和可读性,我们只选择需要的特定列列名之间用逗号分隔,顺序可以任意指定,不必与表中的列顺序相同SELECT student_id,name,grade FROM students;使用列别名可以使用AS关键字为列指定别名,使结果集更易读或解决列名冲突AS关键字是可选的,可以省略如果别名包含空格,需要使用引号SELECTstudent_id ASID,name ASStudent Name,grade AS成绩FROM students;简单条件查询()WHERE子句基础比较运算符WHEREWHERE子句用于过滤符合特定条件的记录,它跟在•=等于(SELECT*FROM studentsWHEREFROM子句之后只有满足WHERE条件的行才会出age=20;)现在查询结果中WHERE子句使用各种比较和逻辑•、大于、小于(SELECT*FROM products运算符来构建条件表达式WHERE price100;)•=、=大于等于、小于等于(SELECT*SELECT*FROM studentsWHERE grade=FROM ordersWHERE order_date=2023-01-80;01;)•、!=不等于(SELECT*FROM employeesWHEREdepartmentSales;)逻辑运算符•AND满足所有条件(SELECT*FROM studentsWHEREgrade=80AND attendance90;)•OR满足任一条件(SELECT*FROM productsWHERE category=电子OR category=配件;)•NOT条件取反(SELECT*FROM employeesWHERE NOTdepartment=HR;)逻辑运算符可以组合使用,创建复杂的条件使用括号可以明确指定运算顺序,提高可读性并避免歧义SELECT*FROM productsWHERE category=电子OR category=配件AND price1000;、、用法BETWEEN INLIKE123运算符运算符模式匹配BETWEEN INLIKEBETWEEN用于指定一个包含的范围查询,包括边界值它等价于大IN运算符用于检查是否匹配列表中的任何一个值,是多个OR条件的LIKE运算符用于字符串模糊匹配,搭配通配符使用常用通配符于等于并且小于等于的组合条件,但表达更简洁简化写法特别适合当需要过滤大量可能值时有%(匹配任意长度的任意字符序列)和_(匹配单个任意字符)--查询价格在100到500之间的产品--查询指定类别的产品SELECT*FROM productsSELECT*FROM products--查询名称以智能开头的产品WHERE priceBETWEEN100AND500;WHERE categoryIN电子,配件,数码;SELECT*FROM productsWHERE product_name LIKE智能%;--等价于--等价于SELECT*FROM productsSELECT*FROM products--查询名称中包含手机的产品WHERE price=100AND price=500;WHERE category=电子SELECT*FROM productsOR category=配件WHEREproduct_name LIKE%手机%;ORcategory=数码;--查询以字母M开头,恰好6个字符的产品型号SELECT*FROM productsWHEREmodel LIKEM_____;值判断NULL理解值NULL在SQL中,NULL表示未知或缺失的值,而不是零或空字符串NULL有特殊的性质任何与NULL的比较操作(包括NULL与NULL的比较)都会返回NULL,而不是真或假因此,不能使用普通的比较运算符(如=或)来检查NULL值运算符IS NULL要检查字段是否为NULL,必须使用专门的IS NULL运算符--查找缺失电话号码的客户SELECT*FROM customersWHEREphone ISNULL;运算符IS NOT NULL相反,要查找非NULL值的记录,使用IS NOTNULL运算符--查找有电话号码的客户SELECT*FROM customersWHEREphone ISNOTNULL;注意事项WHERE子句中的条件表达式不会选择NULL值例如,WHERE age20不会返回年龄字段为NULL的记录在处理可能包含NULL值的列时,需要明确考虑NULL的情况,可能需要使用COALESCE或IFNULL等函数来提供默认值--使用COALESCE替换NULL为默认值SELECT name,COALESCEphone,未提供FROM customers;排序查询()ORDER BY基本排序多列排序ORDER BY子句用于对查询结果集进行排序,它通常是SELECT语句中当需要按多个列排序时,ORDER BY子句可以包含多个列名,用逗号最后执行的子句排序可以按单个或多个列进行,每列都可以指定升分隔结果首先按第一个列排序,然后在第一个列值相同的情况下,序或降序再按第二个列排序,依此类推--按成绩降序排列学生--先按部门升序,再按薪资降序排列员工SELECT*FROM studentsSELECT*FROM employeesORDER BY gradeDESC;ORDER BY department ASC,salary DESC;默认情况下,ORDER BY使用升序(ASC)排序ASC关键字可以省此查询首先按部门名称字母顺序排序,然后在同一部门内,再按薪资略,但为了代码清晰度,建议明确指定排序方向从高到低排序这种多级排序在处理复杂数据时非常有用,可以创建更有意义的结果展示--等价的查询,明确指定升序排序也可以使用列的位置索引(从1开始)替代列名,但这不是推荐SELECT*FROM students的做法,因为它降低了代码的可读性,且在SELECT列表更改时容易ORDER BYname ASC;出错查询结果去重()DISTINCT单列去重从单个列中移除重复值多列去重基于多列组合的唯一值和其他子句结合结合WHERE、ORDER BY等使用DISTINCT关键字用于去除查询结果中的重复行,它放在SELECT关键字之后在单列去重时,DISTINCT会返回该列中所有不重复的值,这在查询唯一类别或属性时特别有用--查询系统中所有不同的部门SELECT DISTINCTdepartment FROM employees;对于多列去重,DISTINCT会基于所有指定列的组合进行去重只有当所有列的值完全相同时,行才被视为重复--查询不同的部门-职位组合SELECT DISTINCTdepartment,job_title FROM employees;DISTINCT可以与其他子句(如WHERE、ORDER BY)结合使用ORDER BY通常放在DISTINCT之后,以便对去重后的结果进行排序--查询并排序所有不同的客户城市SELECT DISTINCTcity FROM customersWHERE country=中国ORDER BYcity;聚合函数入门函数函数函数COUNT SUMAVGCOUNT函数计算符合条件的行数它有几种变SUM函数计算指定列中所有值的总和,仅适用于AVG函数计算指定列的平均值,仅适用于数值类体COUNT*计算表中的所有行;数值类型的列NULL值会被忽略型的列NULL值会被忽略,不计入平均值计算COUNTcolumn计算指定列中非NULL值的行数;COUNTDISTINCT column计算指定列中不重复的--计算所有产品库存总量非NULL值的数量SELECT SUMquantityFROM products;--计算学生平均成绩SELECT AVGgradeFROM students;--统计学生总数--计算特定类别产品的总价值SELECT COUNT*FROMstudents;SELECT SUMprice*quantity--计算各科目平均分FROM productsSELECT subject,AVGscore--统计有电子邮件的学生数WHEREcategory=电子;FROM exam_resultsSELECT COUNTemailFROMstudents;GROUP BYsubject;--统计不同年龄的学生数SELECT COUNTDISTINCTage FROMstudents;和函数MIN MAXMIN函数返回指定列中的最小值,MAX函数返回最大值它们可用于数值、字符串和日期类型的列--找出最高和最低成绩SELECTMINgrade AS最低分,MAXgrade AS最高分FROMstudents;分组查询()GROUP BY基本分组GROUP BY子句对结果集按一个或多个列的值进行分组,然后对每个组应用聚合函数这允许对数据进行汇总分析,例如计算每个类别的总计或平均值--统计每个部门的员工数SELECT department,COUNT*AS员工数FROM employeesGROUP BY department;多列分组GROUP BY可以使用多个列,先按第一个列分组,然后在每个主组内再按第二个列分组,依此类推这允许创建层次化的数据汇总--统计每个部门中各职位的员工数SELECTdepartment,job_title,COUNT*AS员工数FROM employeesGROUP BY department,job_title;分组与排序GROUP BY分组后,通常需要用ORDER BY对结果进行排序注意GROUP BY和ORDER BY的顺序GROUP BY在WHERE之后,ORDER BY在最后--按销售额降序排列的产品类别SELECTcategory,SUMprice*quantity AS销售额FROM salesGROUP BY categoryORDER BY销售额DESC;分组筛选()HAVING与的区别基本语法HAVING WHEREHAVING和WHERE都用于条件筛选,但作用的阶段不同WHERE在分组HAVING子句紧跟在GROUP BY之后,对分组结果进行过滤只有满足前过滤单个行,而HAVING在分组后过滤组HAVING子句通常包含聚合HAVING条件的组才会出现在最终结果中HAVING条件通常(但不总函数(如COUNT、SUM),这是它与WHERE的主要区别是)含有聚合函数执行顺序常见用途SQL查询子句的执行顺序通常是FROM→WHERE→GROUP BY→HAVING最常用于筛选特定数量或统计特征的组,例如找出员工数超过10HAVING→SELECT→ORDER BY理解这个顺序有助于编写高效的查人的部门或平均成绩超过85分的班级这类查询无法用WHERE实现,询因为它们依赖于分组后计算的聚合值以下是HAVING的几个实际应用示例--找出平均成绩超过80分的班级SELECT class_id,AVGgrade AS平均分FROM studentsGROUPBY class_idHAVING平均分80;--找出总销售额超过100000元的产品类别SELECT category,SUMprice*quantity AS总销售额FROM salesGROUPBY categoryHAVING总销售额100000ORDER BY总销售额DESC;限制查询记录数()LIMIT/TOP的用法的用法MySQL LIMITSQL ServerTOP在MySQL、PostgreSQL和SQLite等数据库中,使用LIMIT子句限制返回的记录数它通常放在在SQL Server中,使用TOP关键字而不是LIMITTOP放在SELECT关键字之后,可以指定具体查询的最后,在ORDER BY之后LIMIT有两种基本语法形式的行数或百分比--返回前5条记录--返回前5条记录SELECT*FROM productsSELECT TOP5*FROM productsORDER BY price DESC ORDER BY priceDESC;LIMIT5;--返回前10%的记录--跳过前10条,返回接下来的5条记录SELECT TOP10PERCENT*FROM productsSELECT*FROM productsORDER BYpriceDESC;ORDER BYprice DESCLIMIT10,5;--或LIMIT5OFFSET10在早期版本的SQL Server中不支持OFFSET功能,但从SQL Server2012开始,可以使用OFFSET-FETCH子句实现类似LIMIT的分页功能第一个参数是偏移量(从0开始),第二个参数是要返回的行数这种语法特别适合分页功能,例如每页显示20条记录--跳过前10条,返回接下来的5条记录SELECT*FROM products--第1页(前20条)ORDER BYprice DESCSELECT*FROM productsLIMIT0,20;OFFSET10ROWS--第2页(第21-40条)FETCH NEXT5ROWS ONLY;SELECT*FROM productsLIMIT20,20;--第3页(第41-60条)使用LIMIT或TOP时,为了确保结果的一致性,应始终结合ORDER BY子句使用否则,返回的SELECT*FROM productsLIMIT40,20;记录可能是随机的,因为关系数据库不保证行的自然顺序多表关联查询()基础JOIN连接查询的意义在关系型数据库中,数据通常分布在多个相互关联的表中以减少数据冗余连接查询(JOIN)允许我们基于表之间的关系将多个表的数据组合在一起,形成完整的信息视图,这是关系型数据库的核心优势之一连接类型概览SQL提供了多种类型的连接操作,每种适用于不同的数据查询需求内连接(INNER JOIN)仅返回两个表中都有匹配的行左外连接(LEFT JOIN)返回左表的所有行,即使右表没有匹配右外连接(RIGHT JOIN)返回右表的所有行,即使左表没有匹配全外连接(FULL JOIN)返回左表和右表的所有行,无论是否匹配交叉连接(CROSS JOIN)返回两个表的笛卡尔积,即所有可能的行组合连接条件(子句)ON除了交叉连接外,其他类型的连接都需要指定一个条件(通常通过ON子句)来确定如何匹配两个表的行这个条件通常涉及主键和外键的关系,但也可以是任何有效的比较表达式正确设置连接条件对于获取预期结果至关重要选择合适的连接类型选择哪种类型的连接取决于您的查询需求例如,如果您只想查看有匹配订单的客户,使用内连接;如果您想查看所有客户,无论他们是否有订单,则使用左连接(假设客户是左表)理解各种连接类型的差异对编写高效的SQL查询至关重要语法与应用INNER JOIN内连接基本概念实际应用案例内连接(INNER JOIN)是最常用的连接类型,它返回两个表中满足连接条件的匹配行不假设我们有两个表customers(客户表)和orders(订单表),它们通过customer_id字符合连接条件的行将被排除在结果集之外内连接的语法使用关键字JOIN或INNER JOIN段关联以下案例展示了内连接的典型应用场景(两者等价)--查询所有有订单的客户及其订单信息SELECT columnsSELECT c.customer_id,c.name,o.order_id,o.order_date,o.amountFROM table1FROM customersc[INNER]JOIN table2INNER JOIN orders o ON c.customer_id=o.customer_id;ON table
1.column=table
2.column;--查询每个客户的订单总金额内连接的特点是只返回两个表都存在的数据,这使得它特别适合查询必须同时存在于两个SELECT c.customer_id,c.name,SUMo.amount AStotal_amountFROM customersc表中的关联数据,例如查询所有有订单的客户INNER JOINorders oON c.customer_id=o.customer_idGROUP BYc.customer_id,c.name;--多表内连接(三个或更多表)SELECT c.name,o.order_id,p.product_nameFROM customerscINNER JOINorders oON c.customer_id=o.customer_idINNER JOINorder_items oiON o.order_id=oi.order_idINNER JOINproducts pON oi.product_id=p.product_idWHERE o.order_date2023-01-01;与LEFT JOINRIGHT JOIN外连接扩展了内连接的概念,允许返回即使没有匹配行的记录LEFT JOIN(左外连接)返回左表的所有行,无论右表是否有匹配值;RIGHT JOIN(右外连接)返回右表的所有行,无论左表是否有匹配值LEFT JOIN的基本语法SELECT columnsFROM table1LEFT[OUTER]JOIN table2ON table
1.column=table
2.column;RIGHT JOIN的基本语法类似,只是方向相反SELECT columnsFROM table1RIGHT[OUTER]JOIN table2ON table
1.column=table
2.column;与FULL JOINCROSS JOIN全外连接()交叉连接()FULL JOINCROSS JOIN全外连接返回左表和右表中的所有行,无论它们是否有匹配交叉连接返回两个表的笛卡尔积,即左表中的每一行与右表当左表或右表中的行没有匹配时,结果中来自另一表的列将中的每一行配对结果集的行数等于两个表行数的乘积交填充NULL值全外连接结合了LEFT JOIN和RIGHT JOIN的功叉连接不需要ON子句,因为它不基于任何条件进行匹配能SELECT columnsSELECT columnsFROM table1FROMtable1FULL[OUTER]JOIN table2CROSS JOINtable2;ON table
1.column=table
2.column;交叉连接在创建测试数据或需要所有可能组合的情况下很有全外连接在查找不匹配的记录或执行数据完整性检查时特别用,例如生成所有可能的产品-颜色组合但在大型表上使有用,例如查找没有相应订单的客户和没有相应客户的订单用交叉连接要谨慎,因为结果集可能非常大,导致性能问题需要注意的是,MySQL不直接支持FULL JOIN,但可以使用UNION结合LEFT JOIN和RIGHT JOIN模拟实现连接选择建议选择合适的连接类型取决于您的查询需求•当需要两个表都存在的数据时,使用INNER JOIN•当需要确保左表所有行都出现在结果中时,使用LEFT JOIN•当需要确保右表所有行都出现在结果中时,使用RIGHT JOIN•当需要两个表的所有行,无论是否匹配时,使用FULL JOIN•当需要所有可能的组合时,使用CROSS JOIN在实践中,内连接和左外连接是最常用的连接类型,能够满足大多数查询需求子查询用法表子查询返回多行多列,在FROM子句中使用行子查询返回单行多列,常用于比较列子查询返回多行单列,常用于IN条件标量子查询返回单行单列,用作表达式子查询是嵌套在另一个SQL查询中的查询,可以出现在SELECT、FROM、WHERE或HAVING子句中子查询必须用括号括起来,可以返回不同形式的结果集,影响其使用方式标量子查询返回单个值,可以在任何允许表达式的地方使用--获取高于平均价格的产品SELECT*FROM productsWHEREpriceSELECT AVGpriceFROM products;列子查询返回单列多行,常用于IN、ANY、ALL等运算符--查询有订单的客户SELECT*FROM customersWHERE customer_id IN SELECT DISTINCT customer_id FROM orders;行子查询和表子查询更为复杂,通常用于比较或作为数据源--使用表子查询作为派生表SELECT dept_name,avg_salaryFROM SELECT department_id,AVGsalary asavg_salaryFROM employeesGROUPBYdepartment_id ASdept_avgJOIN departmentsd ONdept_avg.department_id=d.id;与EXISTS NOTEXISTS运算符EXISTSEXISTS运算符用于测试子查询是否返回任何行如果子查询返回至少一行,EXISTS条件为真;如果子查询不返回任何行,EXISTS条件为假与其他子查询不同,EXISTS子查询通常使用相关子查询,即子查询引用外部查询的列--查询有订单的客户SELECT*FROM customerscWHERE EXISTS SELECT1FROM orders oWHERE o.customer_id=c.customer_id;运算符NOT EXISTSNOTEXISTS与EXISTS相反,当子查询没有返回任何行时条件为真它通常用于查找不满足特定条件的记录--查询没有订单的客户SELECT*FROMcustomerscWHERE NOTEXISTSSELECT1FROMorders oWHERE o.customer_id=c.customer_id;与的区别INEXISTS和IN都可用于子查询,但它们的工作方式不同EXISTS检查子查询是否返回任何行,而不关心具体返回的值;IN检查外部查询的值是否匹配子查询返回的任何值通常对于大型数据集,EXISTS的性能更好,特别是当子查询包含大量行时--使用IN的等效查询SELECT*FROM customersWHERE customer_id INSELECT customer_id FROMorders;性能考虑EXISTS子查询中通常使用SELECT1(或任何常量)而不是选择实际列,因为EXISTS只关心是否存在匹配行,不关心返回的值此外,EXISTS一旦找到一个匹配行就会停止处理,而IN需要评估子查询返回的所有值,这使得EXISTS在某些情况下更高效插入数据()INSERT单行插入多行插入12INSERT INTO语句用于向表中添加新记录最基本的形式是指定表名和要插入的值可以为所有列或特定列提供值当不为提高效率,可以在一条INSERT语句中插入多行数据每组值用括号括起来,组之间用逗号分隔这种方法比多次执行为所有列提供值时,必须明确列出要插入数据的列名单行插入更高效,尤其是批量导入数据时--为所有列提供值(按表定义顺序)INSERT INTO products product_id,name,priceINSERT INTOcustomers VALUESVALUES1,张三,上海市,13812345678;1,笔记本电脑,
5999.99,2,智能手机,
3999.00,--为特定列提供值3,无线耳机,
899.00,INSERT INTOcustomers id,name,phone4,平板电脑,
2999.50;VALUES2,李四,13987654321;使用插入数据处理重复或冲突3SELECT4INSERT INTO...SELECT语句允许从其他表查询数据并插入到目标表中这对于数据复制、归档或从临时表移动数据非常当插入可能违反唯一约束(如主键重复)时,不同数据库系统提供了不同的处理方式MySQL提供ON DUPLICATEKEY有用SELECT查询可以包含WHERE、JOIN等子句,从而提供灵活的数据选择方式UPDATE子句,而PostgreSQL和SQLite提供ON CONFLICT子句(UPSERT功能)--将旧用户复制到归档表--MySQL的处理方式INSERT INTOusers_archive INSERT INTO productsid,name,stockSELECT*FROM usersVALUES101,智能手表,50WHERE last_login2022-01-01;ON DUPLICATEKEY UPDATEstock=stock+50;--选择性地复制数据--PostgreSQL的处理方式INSERT INTOmonthly_sales month,product_id,sales_amount INSERTINTOproductsid,name,stockSELECT VALUES101,智能手表,50MONTHorder_date ASmonth,ON CONFLICTid DOUPDATE SETstock=products.stock+50;product_id,SUMamount ASsales_amountFROM ordersWHEREYEARorder_date=2023GROUPBYMONTHorder_date,product_id;更新数据()UPDATE基本语法高级技巧UPDATE UPDATEUPDATE语句用于修改表中已存在的记录其基本语法包括指定表名、要更新的列及其新值,以及可选的使用表达式SET子句中可以使用表达式,而不仅仅是常量值这对于增量更新特别有用WHERE子句来筛选要更新的行--将所有产品价格提高10%UPDATE table_name UPDATEproductsSET column1=value1,column2=value2,...SET price=price*
1.1;WHERE condition;使用多表UPDATE在某些数据库系统(如MySQL)中,可以基于多个表的条件更新数据如果不指定WHERE子句,UPDATE将修改表中的所有行,这通常不是我们想要的结果因此,执行UPDATE操作前务必仔细检查WHERE条件--MySQL多表更新语法UPDATE customersc--更新单个客户的电话号码JOINordersoON c.customer_id=o.customer_idUPDATE customersSET c.status=VIPSET phone=13900001111WHERE o.total_amount10000;WHEREcustomer_id=1;使用子查询可以在SET子句或WHERE子句中使用子查询--将没有订单的客户标记为非活跃UPDATE customersSETactive=0WHEREcustomer_id NOTINSELECTDISTINCTcustomer_idFROM ordersWHERE order_date2023-01-01;删除数据()DELETE基本语法条件删除DELETEDELETE语句用于从表中删除现有记录其基本语法非常简单,但功能强大通常使用WHERE子句可以精确指定要删除的记录这是最常见的DELETE用法,可以配合WHERE子句使用,以便只删除符合特定条件的记录基于各种条件(如ID、日期范围或状态)删除记录删除所有行使用子查询4不带WHERE子句的DELETE会删除表中的所有行,但保留表结构这与DELETE也可以结合子查询使用,以便基于其他表的数据删除记录这在需要从多TRUNCATE TABLE不同,后者更快但不能回滚使用不带WHERE的DELETE需要个相关表中清理数据时非常有用格外小心基本DELETE语法示例DELETE FROMtable_nameWHERE condition;DELETE的实际应用案例--删除特定客户DELETE FROM customersWHERE customer_id=10;--删除过期订单DELETE FROMordersWHEREorder_date2022-01-01AND status=已完成;--使用子查询删除DELETE FROMproductsWHERE product_id INSELECT product_idFROM inventoryWHEREquantity=0AND last_sold_date2022-06-01;--删除所有记录(谨慎使用)DELETE FROMtemp_logs;事务基础()Transaction事务概念特性ACID事务是一组作为单一逻辑工作单元执行的SQL原子性(Atomicity)事务中的所有操作要语句,它们要么全部成功执行,要么全部失么全部完成,要么全部不完成败事务确保数据库操作的原子性、一致性、一致性(Consistency)事务必须使数据库隔离性和持久性(ACID特性)事务对于处理从一个一致状态转变为另一个一致状态银行转账、订单处理等需要保持数据一致性的操作尤为重要隔离性(Isolation)事务执行不受其他事务的干扰持久性(Durability)一旦事务提交,其结果就是永久的事务控制命令SQL提供了以下命令来控制事务BEGIN TRANSACTION标记事务的开始(在某些数据库中是START TRANSACTION)COMMIT将所有更改永久保存并结束事务ROLLBACK撤销自事务开始以来的所有更改SAVEPOINT在事务中创建一个保存点,用于稍后的部分回滚ROLLBACK TO回滚到特定的保存点视图()基本概念VIEW视图定义视图与表的区别视图的主要用途视图是基于SQL查询的虚拟表,它不存储存储表存储实际数据,视图只存储查简化复杂查询可以将复杂的多表连接实际数据,而是在每次访问时执行底层询定义查询封装在视图中,使最终用户只需执查询视图提供了一种封装查询逻辑的行简单的SELECT语句修改表中的数据可以直接修改,而视方式,允许用户以一致的方式访问数图中的数据修改受限(某些简单视图可数据安全可以通过视图限制用户访问据,而无需了解底层表结构的复杂性以更新)敏感列,只公开他们需要的数据依赖性视图依赖于底层表,如果表结数据抽象视图可以屏蔽底层表结构的视图实际上是存储在数据库中的预定义构改变,视图可能需要更新变化,提供一致的接口给应用程序SQL查询,用户可以像查询普通表一样查询视图当查询视图时,数据库引擎会性能对于复杂查询,视图可能比直接执行视图定义中的查询,然后返回结查询表性能更低,因为它在每次访问时数据独立性应用程序可以基于视图编果都执行查询写,这样当底层表结构变化时,只需更新视图定义,而不需要修改应用程序创建与管理视图创建视图使用CREATE VIEW语句创建视图,需要指定视图名称和定义视图的SELECT查询视图可以包含简单的单表查询,也可以包含复杂的多表连接、聚合和子查询--创建简单视图CREATE VIEWactive_customers ASSELECT*FROM customersWHEREstatus=active;--创建包含连接和聚合的复杂视图CREATE VIEWcustomer_order_summary ASSELECTc.customer_id,c.name,COUNTo.order_id ASorder_count,SUMo.amount AStotal_spentFROM customerscLEFT JOINordersoON c.customer_id=o.customer_idGROUP BYc.customer_id,c.name;修改视图使用ALTER VIEW或CREATE ORREPLACE VIEW语句可以修改现有视图的定义修改视图不会影响任何依赖于该视图的权限或存储过程--使用ALTER VIEW(某些数据库支持)ALTER VIEWactive_customers ASSELECT*FROMcustomersWHEREstatus=active ANDlast_order_date2023-01-01;--使用CREATE ORREPLACE VIEW(更常见)CREATE ORREPLACE VIEWcustomer_order_summary ASSELECTc.customer_id,c.name,c.email,COUNTo.order_id ASorder_count,SUMo.amount AStotal_spentFROM customerscLEFT JOINordersoONc.customer_id=o.customer_idGROUP BYc.customer_id,c.name,c.email;索引()简介INDEX索引的作用提高数据库查询速度的数据结构索引类型不同用途的索引结构和实现索引创建与管理建立和维护索引的SQL命令索引是数据库中用于提高查询性能的特殊数据结构,类似于书籍的目录没有索引时,数据库必须进行全表扫描来找到匹配的行;有了索引,数据库可以直接定位到匹配的行,大大减少了磁盘I/O操作和查询时间常见的索引类型包括B-树索引最常用的索引类型,适用于等值查询、范围查询和排序操作哈希索引仅适用于等值查询,但速度极快全文索引专为搜索文本内容而设计空间索引用于地理空间数据查询创建索引的基本语法--创建基本索引CREATE INDEX idx_name ONtable_namecolumn1,column2;--创建唯一索引(防止重复值)CREATE UNIQUEINDEXidx_email ON usersemail;--删除索引DROP INDEXidx_name;注入防范SQL12注入原理参数化查询SQLSQL注入是一种常见的网络安全漏洞,攻击者通过在应用程序输入中插入恶防止SQL注入的最佳方法是使用参数化查询(也称为预处理语句)参数化意SQL代码,使其在后端数据库中执行当应用程序直接拼接用户输入来构查询将SQL语句与数据分开处理,确保用户输入永远不会被解释为SQL代码的建SQL查询时,就会出现这种风险例如,以下登录查询很容易受到攻击一部分大多数编程语言和数据库API都支持参数化查询query=SELECT*FROM usersWHERE username=+--在Java JDBC中username+PreparedStatement stmt=conn.prepareStatement AND password=+password+;SELECT*FROM usersWHERE username=AND password=;如果用户输入username为admin--,密码为任意值,构建的查询将变为stmt.setString1,username;stmt.setString2,password;SELECT*FROM usersWHERE username=admin--AND--在PHP PDO中password=任意值;$stmt=$pdo-prepareSELECT*FROM usersWHERE username=ANDpassword由于--是SQL注释符号,密码验证部分会被注释掉,允许攻击者无需密码即=;可登录admin账户$stmt-execute[$username,$password];3其他防护措施除了参数化查询,还应采取其他措施加强数据库安全•最小权限原则应用程序连接数据库的账户应只拥有必要的最小权限•输入验证在服务器端验证所有用户输入,拒绝不符合预期格式的输入•错误消息控制不要向用户显示详细的数据库错误信息•定期更新保持数据库和应用程序库的最新补丁•使用ORM框架许多现代ORM框架自动提供SQL注入防护数据备份与恢复数据库备份方法数据恢复过程备份策略与计划数据库备份是防止数据丢失的关键措施备份可数据恢复是将备份数据重新加载到数据库的过有效的备份策略应考虑以下因素以是物理级别的(复制数据文件)或逻辑级别的程根据备份方法的不同,恢复过程也有所不•备份频率根据数据更改频率和重要性确定(通过SQL导出数据)各数据库系统提供了专用同对于SQL导出的备份,可以使用SQL客户端工•备份类型完整备份、增量备份或差异备份的备份工具,如MySQL的mysqldump、具或命令行接口执行备份脚本PostgreSQL的pg_dump和SQL Server的备份功•备份存储备份应存储在与生产服务器不同能的位置mysql-u username-p database_name使用SQL语句,可以将数据导出到SQL脚本文件backup.sql•备份测试定期测试备份的可恢复性中,这些脚本包含重建数据库结构和数据的命•备份自动化使用脚本或任务调度程序自动令例如,使用mysqldump导出MySQL数据库恢复之前,通常需要先创建一个空数据库(除非执行备份使用现有数据库)恢复大型数据库可能需要相当长的时间,在此期间应避免其他数据库操作mysqldump-u username-pdatabase_namebackup.sql数据同步与迁移除了备份和恢复,有时也需要在不同环境之间同步或迁移数据库SQL可以用于创建数据同步脚本,或使用专门的ETL(提取、转换、加载)工具例如,可以使用INSERTINTO...SELECT从一个表复制数据到另一个表,或使用MERGE(某些数据库支持)进行数据合并常见内建函数条件表达式CASE WHEN基本语法实际应用场景CASE表达式是SQL中的条件表达式,类似于其他编程语言中的if-then-else语句它有两种基本形式简单CASE表达式和搜索数据分类根据值范围或条件对数据进行分类CASE表达式SELECT简单CASE表达式将表达式与一系列值进行比较product_name,price,CASE expressionCASEWHEN value1THEN result1WHEN price100THEN低价WHENvalue2THEN result2WHEN priceBETWEEN100AND500THEN中价...ELSE高价[ELSE default_result]END ASprice_categoryENDFROM products;搜索CASE表达式评估一系列布尔表达式条件计算根据条件执行不同的计算CASESELECTWHEN condition1THEN result1order_id,WHEN condition2THEN result2amount,...CASE[ELSE default_result]WHEN amount1000THEN amount*
0.9--大额订单9折ENDWHEN amount500THEN amount*
0.95--中额订单95折ELSE amount--小额订单不打折如果没有匹配的条件且没有提供ELSE子句,CASE表达式将返回NULLEND ASdiscounted_amountFROM orders;动态排序根据参数或条件确定排序方式SELECT*FROM employeesORDERBYCASE@sort_typeWHEN1THEN last_nameWHEN2THEN hire_dateWHEN3THEN salaryELSEemployee_idEND;子句与WITH CTE概念基本语法应用示例CTE CTECTECTE(Common TableExpression,公共表表达式)是一种临时结WITH子句定义一个或多个CTE,每个CTE都有一个名称和一个查询CTE可以简化复杂的多级聚合、自连接或子查询例如,计算部门果集,使用WITH子句定义,只在单个SQL语句执行期间存在CTE定义定义完成后,可以在主查询或其他CTE中引用这些临时结果平均工资并找出高于平均水平的员工类似于派生表,但语法更清晰,可读性更高,并且支持自引用(递集归)WITH dept_avg ASCTE的主要优点包括提高SQL可读性、简化复杂查询、支持递归查WITH cte_name[column_names]ASSELECTdepartment_id,AVGsalary AS询和可重用子查询逻辑与视图不同,CTE不存储在数据库中,仅--CTE查询定义avg_salary在包含它的查询执行期间有效SELECT...FROMemployeesGROUPBYdepartment_id--主查询SELECT...FROM cte_name...;SELECT e.employee_id,e.name,e.salary,d.avg_salary可以在单个WITH子句中定义多个CTE,用逗号分隔FROMemployeeseJOIN dept_avg dON e.department_id=d.department_idWITH使W用H CETREE可e以.s将al复ar杂y查询d分.a解vg为_s更al小a、ry更易管理的部分,提高代码cte1AS SELECT...,可O读R性DE和R维BY护e性.department_id,e.salary DESC;cte2AS SELECT...FROM cte
1...SELECT...FROM cte1JOIN cte
2...;组合查询()UNION/UNION ALL组合查询概念1组合查询允许将多个SELECT语句的结果合并成一个结果集SQL提供了几种集合操作符,最常用的是UNION和UNIONALL这些操作符可以组合来自相同表或不同表的查询结果,前提是这些查询返回相同数量的列,且对应列的数据类型兼容与的区别UNION UNION ALLUNION自动删除结果集中的重复行,而UNION ALL保留所有行,包括重复行由于UNION需要执行去重操作,当确定没有重复行或重复行对结果无影响时,使用UNION ALL会有更好的性能这种性能差异在处理大型结果集时尤为明显基本语法组合查询的基本语法是在多个SELECT语句之间使用UNION或UNION ALL关键字每个SELECT语句必须具有相同数量的列,且对应列的数据类型必须兼容结果集的列名取自第一个SELECT语句SELECT column1,column2,...FROMtable1WHERE conditionUNION[ALL]SELECT column1,column2,...FROMtable2WHERE condition[ORDERBYcolumn1[ASC|DESC]];应用场景示例组合查询适用于多种场景,如合并不同表中的类似数据、合并分区表的结果或创建特定报表例如合并不同地区的销售数据、组合活跃和非活跃用户、创建全面的产品目录或构建复杂的报表查询等当需要将结构相似但来源不同的数据组合在一起时,UNION和UNIONALL是强大而灵活的工具的窗口函数入门MySQL窗口函数概念常用窗口函数窗口函数(也称为分析函数)允许在不改变结果集行数的情况下进行计算它们与聚合函数类似,但不会将结果分组成ROW_NUMBER为分区中的每一行分配唯一的连续整数单行,而是为每一行保留其身份并计算结果窗口函数通过OVER子句定义窗口(一组行),并在这个窗口上执行计算RANK为分区中的每一行分配排名,相同值获得相同排名,但会导致排名间隙MySQL从
8.0版本开始支持窗口函数,为复杂的分析查询提供了强大的工具窗口函数可用于计算累计总和、移动平均值、DENSE_RANK类似于RANK,但没有排名间隙排名、百分比排名等,这些计算在传统SQL中通常需要复杂的自连接或子查询NTILEn将分区中的行分为n个桶,并分配桶号LEAD/LAG访问分区中当前行之后/之前的行FIRST_VALUE/LAST_VALUE返回窗口框架中的第一个/最后一个值SUM/AVG/COUNT在窗口上计算聚合值--计算每个部门员工的薪资排名SELECTemployee_id,name,department,salary,RANK OVERPARTITION BYdepartment ORDERBY salaryDESC ASsalary_rankFROM employees;--计算累计销售额SELECTsale_date,amount,SUMamount OVERORDERBYsale_date AScumulative_salesFROM sales;--计算移动平均SELECTsale_date,amount,AVGamount OVERORDERBYsale_date ROWSBETWEEN2PRECEDING ANDCURRENT ROWAS moving_avgFROM sales;常见错误与调试SQL语法错误语法错误是最常见的SQL错误类型,通常由拼写错误、缺少关键字或标点符号导致例如,忘记在WHERE子句条件之间添加AND/OR、SELECT和FROM之间缺少逗号、或者表名拼写错误大多数数据库系统会提供明确的错误消息,指出语法错误的位置和原因调试建议仔细检查SQL语句的语法,确保所有关键字、标点符号和表名/列名都正确使用代码编辑器的语法高亮功能可以帮助识别语法问题逻辑错误逻辑错误指SQL语句在语法上正确,但不返回预期结果这可能是由于JOIN条件错误、WHERE条件逻辑不正确或GROUPBY/HAVING使用不当导致逻辑错误更难发现,因为查询可以成功执行,但结果与预期不符调试建议分解复杂查询,逐步测试每个部分;使用EXPLAIN/EXPLAIN PLAN分析查询执行计划;添加注释记录每个子句的目的;使用简单的测试数据验证查询逻辑数据类型错误数据类型错误发生在尝试比较或操作不兼容数据类型的数据时例如,将字符串与数字比较、在日期字段上使用字符串函数,或尝试插入不符合列数据类型的值这些错误可能导致隐式转换问题或执行失败调试建议确保了解每个列的数据类型;使用适当的转换函数(如CAST/CONVERT)显式转换数据类型;检查输入数据是否符合目标列的类型要求性能问题性能问题指查询执行时间过长或消耗过多资源这可能是由于缺少适当的索引、使用不必要的表连接、过度使用子查询、或查询条件不够具体导致性能问题在开发环境中可能不明显,但在生产环境中处理大量数据时会变得严重调试建议使用EXPLAIN分析查询执行计划;确保关键查询字段已建立索引;避免使用SELECT*,只查询需要的列;优化JOIN和WHERE条件;考虑使用索引提示或查询重写性能优化建议索引优化策略索引是提高查询性能的最重要工具之一创建合适的索引可以显著减少数据库访问时间,但过多的索引会影响写入性能以下是一些索引优化建议•为WHERE子句、JOIN条件和ORDERBY中频繁使用的列创建索引•为高选择性列(具有许多不同值的列)创建索引,如主键、唯一标识符•考虑创建覆盖索引,包含查询中所有需要的列,避免回表查找•避免过度索引,每个索引都会增加写入操作的开销•定期分析和重建索引以减少碎片查询语句优化优化SQL查询语句可以减少资源消耗并提高响应速度以下是一些查询优化技巧•只查询需要的列,避免使用SELECT*•使用具体的WHERE条件限制结果集大小•避免在WHERE子句中对列使用函数,这会阻止索引使用•小心使用LIKE%关键字%,这种前缀通配符查询无法有效利用索引•合理使用JOIN,避免不必要的表连接,特别是对大型表•对大结果集使用分页查询,限制一次返回的数据量•使用EXPLAIN/EXPLAIN PLAN分析和优化查询执行计划数据库设计优化良好的数据库设计是性能优化的基础优化数据库结构可以从根本上提高查询效率•合理规划表结构和关系,遵循数据库规范化原则•为大型表考虑分区策略,如基于时间或地区的分区•对于读取频繁的应用,考虑适度的反规范化以减少连接•使用适当的数据类型,如使用INT而不是VARCHAR存储数字•设置合理的字段长度,不要过度分配空间•使用存储过程和视图封装复杂逻辑,提高代码复用性实际应用案例1实际应用案例2用户ID用户名注册天数最近登录总活跃天数活跃率活跃等级10001张三1802023-06-
1514580.6%高度活跃10002李四1652023-06-
109859.4%中度活跃10003王五1202023-05-
204537.5%低度活跃以下是一个多表关联查询,用于分析用户活跃度该查询使用users(用户表)、login_logs(登录日志表)和user_actions(用户行为表)三个表,计算用户的注册天数、活跃天数和活跃率等指标--用户活跃度分析SQLWITH user_stats AS--计算用户注册天数和最近登录时间SELECTu.user_id,u.username,DATEDIFFCURRENT_DATE,u.register_date ASdays_since_register,MAXl.login_time ASlast_login,COUNTDISTINCT DATEl.login_time AS active_daysFROM usersuLEFT JOINlogin_logs lONu.user_id=l.user_idWHERE u.register_date=CURRENT_DATE-INTERVAL30DAYGROUP BYu.user_id,u.username,u.register_dateSELECTus.user_id,us.username,us.days_since_register,us.last_login,us.active_days,ROUNDus.active_days/us.days_since_register*100,1ASactive_rate,CASEWHEN us.active_days/us.days_since_register=
0.7THEN高度活跃WHEN us.active_days/us.days_since_register=
0.4THEN中度活跃ELSE低度活跃END ASactive_levelFROM user_stats usORDERBY active_rate DESC;参考资源与书籍推荐官方文档推荐书籍在线学习平台各大数据库系统提供了详尽的官方文档,《SQL必知必会》是入门者的理想选择,W3Schools和菜鸟教程提供了交互式SQL这些是学习和参考的最权威来源特别推简明扼要地介绍SQL基础知识《SQL性能教程,适合初学者LeetCode和荐MySQL参考手册、PostgreSQL文档和优化指南》深入探讨了查询优化技术HackerRank的SQL挑战可以帮助提高实际SQL Server在线文档,它们提供了完整的《MySQL技术内幕InnoDB存储引擎》适问题解决能力Codecademy和DataCamp语法参考、函数说明和使用示例这些文合希望深入了解MySQL内部工作原理的读提供了结构化的SQL课程Stack档通常提供多语言版本,并定期更新以反者《SQL反模式》介绍了常见的SQL设计Overflow是解决特定SQL问题的宝贵资映最新版本的功能和编程错误,以及如何避免它们源,包含大量实际案例和专家解答总结与课堂练习核心知识回顾实践能力培养本课程全面介绍了SQL的基础知识,从基本SQL是一门实践性很强的语言,只有通过大概念和语法到高级查询技术我们学习了量练习才能真正掌握建议设置自己的测数据库和表的创建、数据操作命令、各种试数据库,尝试编写各种类型的查询从查询方法、索引和视图等重要概念特别简单的SELECT语句开始,逐步尝试复杂的强调了连接查询、子查询、聚合函数等实连接查询、子查询和聚合分析分析和理用技术,这些都是日常数据库操作的核心解查询的执行计划也是提高SQL技能的重要工具方面持续学习路径项目实战建议SQL学习是一个持续的过程掌握基础知识将SQL学习与实际项目结合是最有效的学习后,可以进一步学习特定数据库系统的高方法尝试设计一个小型数据库项目,如级特性、性能优化技术、数据库设计原则图书管理系统、个人财务跟踪器或博客平和数据仓库概念跟踪行业最新发展,如台实现从数据库设计、表创建到数据查NewSQL、时序数据库等新技术也很重要询和报表生成的完整流程,这将帮助巩固参与开源项目或SQL相关社区可以提供宝贵所学知识并培养实际应用能力的实践经验和交流机会。
个人认证
优秀文档
获得点赞 0