SQL快速入门 ( MySQL快速入门, MySQL参考, MySQL快速回顾 )

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: SQL先说点废话,很久没发文了,整理了下自己当时入门 SQL 的笔记,无论用于入门,回顾,参考查询,应该都是有一定价值的,可以按照目录各取所需。SQL数据库有很多,MySQL是一种,本文基本都是SQL通用标准,有些标准很不统一的地方就用MySQL的写法了。

SQL

先说点废话,很久没发文了,整理了下自己当时入门 SQL 的笔记,无论用于入门,回顾,参考查询,应该都是有一定价值的,可以按照目录各取所需。SQL数据库有很多,MySQL是一种,本文基本都是SQL通用标准,有些标准很不统一的地方就用MySQL的写法了。希望本文帮你快速了解SQL的基本操作和概念。
文章格式上有些问题,可以点击这里获得更加的阅读体验

目录

检索

  • 检索某表中单个列:
    SELECT 列名
    FROM 表名;
  • 检索某表中多个列:
    SELECT 列名,列名,列名
    FROM 表名;
  • 检索某表中所有列:(尽量不用)
    SELECT *
    FROM 表名;
  • 只检索某表中某列里不重复的项:
    SELECT DISTINCT 列名 (如果有两列或以上,需要这些列组合起来是不重复的)
    FROM 表名;
  • 检索指定行数:
    SELECT 列名
    FROM 表名
    LIMIT 5 OFFSET n; (mySQL中,选第n行后的五行。 OFFSET n 可不填写默认为0,其它 SQL 数据库中有不同写法)

过滤检索结果

  • 寻找指定行:(举例)
    SELECT prod_name, prod_price  
    FROM Products  
    WHERE prod_price = 3.49;(和字符串比较加单引号,数值不用)
查找列名为prod_name和列名为prod_price的两列,检索其中prod_price = 3.49; 的所有行。  
= 可以替换为其它操作符,如下表

| 操作符 | 描述 |
| --- | --- |
| = | 等于 |
| <> | 不等于 |
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
| BETWEEN | 在某个范围内 |
| LIKE | 搜索某种模式 |
  • 组合WHERE子句:
    SELECT prod_id, prod_price, prod_name
    FROM Products
    WHERE vend_id = 'DLL01' AND prod_price <= 4;
AND 连接同时需要满足的两个条件,OR即满足一个条件即可,NOT 找到与后边条件不匹配的行。  
且not,and和or可以组合使用,用小括号声明逻辑循序。  
`WHERE vend_id IN ( 'DLL01', 'BRS01' ) `  
IN 起到作用类似于or,速度更快,逻辑更清晰。
  • 通配符搜索:
    SELECT prod_id, prod_name
    FROM Products
    WHERE prod_name LIKE '%bean bag%';
%表示任意字符出现任意次数。也可以出现在中间位置。  
_ 表示一个字符。  
[charlist] 表示包含在里面的任意字符,[^charlist]不包含在里面的任意字符。
少使用通配符,搜索速度较慢。  

数据汇总处理

  • 算术计算:
    SELECT prod_id,
            quantity,
            item_price,
            quantity * item_price AS expanded_price
    FROM OrderItems
    WHERE order_num = 20008;
`expanded_price`成为计算出来的新列。
  • 字符串拼接:
    不同数据库有差异,MySQL中:
    SELECT concat(vend_name , vend_country)
            AS vend_title
    FROM Vendors
    ORDER BY vend_name;
concat_ws( ':' , vend_name , vend_country) 形式第一个参数为分隔符。  
其他数据库用+或者||拼接字符串。
  • 日期时间处理不同数据库差异较大。
  • 内置方法:
    • 求平均值:
      SELECT AVG(prod_price) AS avg_price
      FROM Products;
      表Products中prod_price的平均值。返回给 avg_price。
      可以配合WHERE语句计算指定行的平均值。
    • 求最大值:MAX(prod_price)
    • 求最小值:MIN(prod_price)
    • 求和:SUM(prod_price)
    • 近似的小数点后几位:ROUND(column_name,decimals)
    • 当前日期: Now()
    • 求行数:
      SELECT COUNT(*) AS num_cust
      FROM Customers;
      求表Customers有几行。返回给num_cust。
      *可以换成指定列如:cust_email。计算所得行数不包括该列值为null的行。
      DISTINCT 列名,求不重复的列。
  • 组合:
    SELECT COUNT(*) AS num_items,
           MIN(prod_price) AS price_min,
           MAX(prod_price) AS price_max,
           AVG(prod_price) AS price_avg
    FROM Products;

分组

  • 创建分组:
    SELECT vend_id
    FROM Products
    GROUP BY vend_id;
根据 vend_id列中内容对 vend_id分组,  
第一行换成 `SELECT vend_id, COUNT(*) AS num_prods` 即对每一个组计算行数。  
注意:多行NULL会分为一组,GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。  
可以对一个以上的列进行 GROUP BY
  • 过滤分组:
    HAVING:类似于WHERE。唯一的差别是,WHERE过滤行,而HAVING过滤分组。
    SELECT vend_id, COUNT(*) AS num_prods
    FROM Products
    WHERE prod_price >= 4
    GROUP BY vend_id
    HAVING num_prods >= 2;
过滤出有(两个价格大与4的产品)的供应商

给检索结果排序

SELECT Company, OrderNumber 
FROM Orders 
ORDER BY Company DESC, OrderNumber ASC  

可以 ORDER BY 列名1,列名2; 先按列名1内容排序,排序结果相同的按列名2内容排序。
列名后接 DESC 按该列内容倒序排列,ASC 正序(默认)。
ORDER BY 命令放在查询、分组等语句的最后。

表操作

  • 创建表:
    CREATE  TABLE  newProducts
    (
        prod_id         CHAR(10)           NOT NULL,
        vend_id         CHAR(10)           NOT NULL,
        prod_name       CHAR(254)          NOT NULL,
        prod_price      DECIMAL(8,2)       NOT NULL,
        prod_desc       VARCHAR(1000)      NULL
    );
NOT NULL 非空约束,不允许列中有NULL值下面介绍其他约束。  
列的设置可以加上默认值,如NOT NULL后边接 DEFAULT  CURRENT_DATE() ,默认值为当前日期。(每个数据库获取当前日期语句不同。)
后面接 PRIMARY KEY 即设置改列为主键。
后面接  AUTO_INCREMENT 即设置为自增,只有int型可以设置。
  • 约束:
    每个列可以有一种或几种约束。
    • NOT NULL 非空约束.
    • UNIQUE 唯一约束,可唯一标识数据库表中的每条记录。
    • PRIMARY KEY 主键约束,唯一标识数据库表中的每条记录,唯一且非空。
    • FOREIGN KEY 外键约束,一个表中的 FOREIGN KEY 指向另一个表中的 PRIMARY KEY。
    • CHECK 检查约束,用于限制列中的值的范围。
    • DEFAULT 默认约束,用于向列中插入默认值
      每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。
      每种约束可以创建表时设置好,也可以后期增删.
  • 索引:
    在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。
    CREATE INDEX 索引名
    ON Person (列名[,列名])  
  • 复制表或表中部分列:
    CREATE  TABLE CustCopy AS
    SELECT * FROM Customers;
创建Customers表的复制,CustCopy。
  • 修改表:
    ALTER TABLE Vendors
    ADD vend_phone CHAR(20);
    ALTER TABLE Vendors
    DROP COLUMN vend_phone;
各数据库有不兼容现象,复杂表操作列可能要新建表删除旧表。  
ALTER 还可以用来添加删除约束,删除索引等。
  • 删除表:
    DROP TABLE CustCopy;
  • 重命名表:
    RENAME Table oldTable TO newTable;

插入数据

  • 插入整行或部分行:
    INSERT INTO Customers(cust_id,
                            cust_name,
                            cust_address,
                            cust_city,
                            cust_state,
                            cust_zip,
                            cust_country,
                            cust_contact,
                            cust_email)
    VALUES('1000000007',
            'Toy Land',
            '123 Any Street',
            'New York',
            'NY',
            '11111',
            'USA',
            NULL,
            NULL);
插入整行时,可省略 Customers 括号内的内容,即按照列的顺序,分别插入数据(不推荐)。省略 Customers 括号内的内容时,无内容的列必须用NULL占位。  
插入部分行时,把要插入的列填入 Customers 括号内,与VALUES内容一一对应,没有提到的列默认NULL或其他默认值。
  • 插入查询到的值:
    INSERT INTO Customers(cust_id,
                            cust_contact,
                            cust_email,
                            cust_name,
                            cust_address,
                            cust_city,
                            cust_state,
                            cust_zip,
                            cust_country)
    SELECT cust_id,
            cust_contact,
            cust_email,
            cust_name,
            cust_address,
            cust_city,
            cust_city,
            cust_state,
            cust_zip,
            cust_country
    FROM CustNew;
把从CustNew表中查到的内容插入 Customers表中。一次插入多行的方式。

更新和删除数据:

  • 更新数据:
    UPDATE Customers
    SET cust_email = 'kim@thetoystore.com'
    WHERE cust_id = '1000000005';
步骤为,要更新的表,要更新的列,要更新的行。一个SET可以跟多个列用逗号隔开。  
删除某个值,即设置他为NULL。
  • 删除数据:
    DELETE FROM Customers
    WHERE cust_id = '1000000008';
删除表中指定整行,删除部分列用UPDATE  
在UPDATE或DELETE语句使用WHERE子句前,应该先用SELECT进行测试,保证它过滤的是正确的记录,以防编写的WHERE子句不正确。如果不写WHERE会更新或删除所有行内容。

子查询-迭代查询

  • 一种形式:
    SELECT cust_name, cust_contact
    FROM Customers
    WHERE cust_id IN (SELECT cust_id
        FROM Orders
        WHERE order_num IN (SELECT order_num
            FROM OrderItems
            WHERE prod_id = 'RGAN01'));
先从第二个括号选择符合条件的order_num,成为第二个括号内容,再向上找到第一个括号,查到符合条件的cust_id返回给第一个括号,最后根据第一个括号内容执行主查询语句。性能问题不要嵌套太多层。  
也就是对Customers表的查询要用到Orders表查询后返回的内容,对Orders表的查询要用到OrderItems表查询后返回的内容。
  • 另一种形式:
    SELECT cust_name,
        cust_state,
        (SELECT COUNT(*)
            FROM Orders
            WHERE Orders.cust_id = Customers.cust_id) AS orders
    FROM Customers
根据Customers 表中的cust_id,去Orders表中取得计算后的数据。  
  • 同一个表迭代查询:
    SELECT cust_id, cust_name, cust_contact
    FROM Customers
    WHERE cust_name = (SELECT cust_name
                    FROM Customers
                    WHERE cust_contact = 'Jim Jones');

联结-关联多个表

  • 两个表:
    • 内联结
          SELECT vend_name, prod_name, prod_price
          FROM Vendors, Products
          WHERE Vendors.vend_id = Products.vend_id;
      根据两个表共同的列vend_id把Vendors, Products关联起来。
      与
          SELECT vend_name, prod_name, prod_price
          FROM Vendors INNER JOIN Products
          ON Vendors.vend_id = Products.vend_id;
      结果相同。都是内联结,前一种是后一种的简写。  
      INNER 可省略。
    • 外联结:
          SELECT Customers.cust_id, Orders.order_num
          FROM Customers LEFT OUTER JOIN Orders
          ON Orders.cust_id = Customers.cust_id;
      LEFT OUTER JOIN 把Customers表中没有被匹配到的 cust_id 也联结进去(会显示在结果里)。  
      RIGHT OUTER JOIN 是把Orders表中没有被匹配到的 cust_id 也联结进去(会显示在结果里)。  
      FULL OUTER JOIN 会把两张表中没有匹配到的列也显示出来(mysql 不支持,可通过 UNION 实现)
      OUTER 可省略。
  • 多个表:
    SELECT cust_name, cust_contact
    FROM Customers, Orders, OrderItems
    WHERE Customers.cust_id = Orders.cust_id
    AND OrderItems.order_num = Orders.order_num
    AND prod_id = 'RGAN01';
作用同子查询中a。同样不要关联太多,有性能问题。其中表名可以使用别名,如:  
    SELECT cust_name, cust_contact
    FROM Customers AS C, Orders AS O, OrderItems AS OI
    WHERE C.cust_id = O.cust_id
    AND OI.order_num = O.order_num
    AND prod_id = 'RGAN01';

组合查询

SELECT cust_name, cust_contact, cust_email 
FROM Customers 
WHERE cust_state IN ('IL','IN','MI') 
UNION ALL
SELECT cust_name, cust_contact, cust_email 
FROM Customers 
WHERE cust_name = 'Fun4All';

UNION ALL 链接两句查询语句,统一返回结果,包含重复结果。
去掉ALL以后,去掉重复结果。
此处(从同一个表中查询)可以用WHERE , OR代替。
常用作从不同表中查询时,只要列数相同就可以拼接到一起,列名按照第一句中查询的列名。

视图

对已存在的表,进行筛选,数据处理,联结等操作后返回的数据,创建的虚拟表。视图是为了重用和简化常用的查询。对视图的查询同表。
视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。

  • 创建视图:
    CREATE  VIEW ProductCustomers AS                
    SELECT cust_name, cust_contact, prod_id
    FROM Customers, Orders, OrderItems
    WHERE Customers.cust_id = Orders.cust_id
    AND OrderItems.order_num = Orders.order_num;
对OrderItems, Orders和Customers三个表进行联结,联结后结果形成 ProductCustomers 视图,可以把它当一张表来查询。
  • 删除视图:
    DROP VIEW ProductCustomers;

    其它

  • 存储过程:为以后的使用保存一条或多条SQL语句,用于简化操作。每个数据库不同,见数据库具体介绍。
  • 事务处理:事务处理模块中的语句,或者全部执行,或者全部不执行。可以设立保留点,执行失败时回到保留点。
  • 创建数据库: CREATE DATABASE database_name
  • 删除数据库:DROP DATABASE 数据库名称

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2天前
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
20天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
18天前
|
SQL 关系型数据库 MySQL
MySQL 高级(进阶) SQL 语句
MySQL 提供了丰富的高级 SQL 语句功能,能够处理复杂的数据查询和管理需求。通过掌握窗口函数、子查询、联合查询、复杂连接操作和事务处理等高级技术,能够大幅提升数据库操作的效率和灵活性。在实际应用中,合理使用这些高级功能,可以更高效地管理和查询数据,满足多样化的业务需求。
56 3
|
21天前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
3天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
13 3
|
3天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
18 3
|
3天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE &#39;log_%&#39;;`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
22 2
|
16天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
115 15
|
10天前
|
SQL 关系型数据库 MySQL
数据库数据恢复—Mysql数据库表记录丢失的数据恢复方案
Mysql数据库故障: Mysql数据库表记录丢失。 Mysql数据库故障表现: 1、Mysql数据库表中无任何数据或只有部分数据。 2、客户端无法查询到完整的信息。
|
17天前
|
关系型数据库 MySQL 数据库
数据库数据恢复—MYSQL数据库文件损坏的数据恢复案例
mysql数据库文件ibdata1、MYI、MYD损坏。 故障表现:1、数据库无法进行查询等操作;2、使用mysqlcheck和myisamchk无法修复数据库。